[英]Preserving parameter/argument names in compiled Java classes
當我編譯這樣的東西時:
public class MyClass
{
void myMethod(String name, String options, String query, String comment)
{
...
}
}
並將其編譯為類文件,似乎參數名稱丟失了。 也就是說,當其他一些 Java 代碼引用MyClass
並想要調用或覆蓋myMethod
時,我的 IDE(當前為 Eclipse)似乎從類文件中獲取了此方法簽名:
void myMethod(String arg0, String arg1, String arg2, String arg3);
我知道 Eclipse(可能還有其他 IDE)允許我提供指向MyClass
的源代碼或 Javadoc (正如 Bishboosh 指出的那樣)的鏈接,並且可以利用這一點。 但是我很好奇是否有某種方法可以告訴javac
將名稱包含到類文件中,以便該類的用戶即使只有類文件也可以看到參數名稱。
當我使用java -g:vars
編譯一個類時,參數的名稱包含在類文件中。 -g:vars
似乎相當於Eclipse -> project properties -> Java compiler -> Add variable attributes to generated class files 。
這個解決方案是由幾位作者提出的,但尼克的回答最終讓我相信了。
在我的機器上,Eclipse 有時使用此信息,有時沒有,這可能是我的錯或 Eclipse 中的錯誤,但不是類文件或編譯的問題。 無論如何,現在我知道信息肯定存在。
雖然這適用於類(有點)好,但它不適用於接口。
對我來說,合乎邏輯的原因似乎是, -g:vars
只提供局部變量的名稱,這也是 javac 的文檔所指出的。 在方法體中,它的參數與局部變量非常相似,因此它們被-g:vars
覆蓋。 接口方法沒有主體,所以它們不能有局部變量。
我最初的問題只要求上課,因為我不知道可能會有任何區別。
正如gid所指出的,類文件格式不支持存儲參數名稱。 我在類文件規范中找到了一個部分,它描述了一個數據結構,它應該包含方法的參數名稱,但這在編譯接口時絕對不會使用。
在編譯一個類時,我無法判斷是否使用了提到的數據結構,或者 Eclipse 是否根據方法體內參數的使用來推斷參數名稱。 專家可以澄清這一點,但我認為這並不重要。
要在類文件中保留名稱以進行調試,請嘗試項目屬性、Java 編譯器,然后“將變量屬性添加到生成的類文件”(參見Eclipse 幫助)。
編譯以下源碼:
public class StackOverflowTest {
public void test(String foo, String bar) {
// blah
}
}
被反編譯成:
// Compiled from StackOverflowTest.java (version 1.5 : 49.0, super bit)
public class StackOverflowTest {
// Method descriptor #6 ()V
// Stack: 1, Locals: 1
public StackOverflowTest();
0 aload_0 [this]
1 invokespecial java.lang.Object() [8]
4 return
Line numbers:
[pc: 0, line: 1]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: StackOverflowTest
// Method descriptor #15 (Ljava/lang/String;Ljava/lang/String;)V
// Stack: 0, Locals: 3
public void test(java.lang.String foo, java.lang.String bar);
0 return
Line numbers:
[pc: 0, line: 4]
Local variable table:
[pc: 0, pc: 1] local: this index: 0 type: StackOverflowTest
[pc: 0, pc: 1] local: foo index: 1 type: java.lang.String
[pc: 0, pc: 1] local: bar index: 2 type: java.lang.String
}
請參閱參數名稱保留在類文件中。
我建議您查看您的源代碼是如何編譯的,它是為哪個版本編譯的等等。
編輯:
啊,我看到這對於接口來說是不同的——它們似乎沒有可用於調試器的這些信息,我認為這是有道理的。 我認為沒有辦法解決這個問題,如果您只想在編輯源代碼時查看參數名稱,則需要按照 Nagrom_17 的建議走 javadoc 路線(附加源代碼)。
您不需要特別需要源來使 arg 名稱出現在 Eclipse 中...如果您指定 Javadoc,Eclipse 將顯示 args。
使用調試支持進行編譯可能會有所幫助,它將所有名稱存儲在 .class 文件中。
雖然我不知道 Eclipse 是否考慮到這一點。
無論您使用什么 javac 選項,類文件數據結構都不支持將參數名稱存儲到任何方法。
為了在 IDE 中查看原始名稱,您必須為它們提供 javadoc 或源代碼。
如果您特別需要在運行時獲取它們,則可以為參數添加注釋,但您必須創建自己的注釋,因為沒有可使用的標准集。
抱歉不能再有幫助了
編輯:我完全糾正了......類文件格式確實有命名參數的空間( JLS 4.7 )
我看不到的是你怎么能用java.lang.reflect.*
如果您在類文件中包含調試信息,Eclipse 將獲取參數的名稱: javac -g:vars
應該足夠了。
您不需要單獨的 Javadoc 文件,您可以在多行注釋的第一個斜杠后使用帶有兩個星號 (*) 的特殊注釋在 Eclipse 中創建“內聯”javadocs。
示例代碼:
public class MyClass
{
/**
* documentation of your method
*
* @param name a String describing the name
* @param options used to describe current option
* @param query
* @param comment
* @return void
*/
void myMethod(String name, String options, String query, String comment)
{
...
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.