众所周知,在Java中,方法名称不足以区分不同的方法。
我认为(可能是错的),要区分方法,需要以下信息:
(className, methodName, methodParameters)
此外,
谢谢!
答案 0 :(得分:6)
CONSTANT_NameAndType_info Structure指向method descriptor。
它几乎由方法名称,参数类型和(有点令人惊讶的)返回类型组成。
答案 1 :(得分:1)
我不太清楚你想要做什么,但我认为尽管有一些可能的答案:
您可能对JNI Method Descriptors感兴趣,string formats是JVM(以及JNI库)内部使用的excellent documentation on the class file format之一,用于识别Java元素。
很难知道你在谈论什么。 “方法id”可以是java.lang.reflect.Method
对象的引用,也可以是下面提到的方法描述符,或任何其他内容。你在哪里读过它?
我怀疑JVM中有这样的表。我的意思是,我怀疑有一个全局表,因为几乎总是从类中检索方法,即使在JVM中处理它,所以它是合理的相信该方法存储在类中。就像我们使用反射来检索方法一样:
Class clazz = String.class;
Method method = clazz.getDeclaredMethod("charAt", Integer.TYPE);
System.out.println(method.getName());
请注意,我向类String
询问方法,而不是要求某些util类为我提供方法charAt
,该方法接收int
并且来自类{{ 1}}。
换句话说,你的识别元组几乎是正确的 - 它只是没有一个类:
String
并且,不是从JVM中检索传递类的方法,而是从方法名称然后是参数类型中检索方法,而是直接从类中检索方法,为类提供方法名称和参数类型。确切地说,这是一个微妙的差异,但我认为这是你想知道的。
即使在我下面提到的JNI描述符中也是如此。例如,方法
(methodName, methodParameters)
由以下描述符表示:
long f(int i, Class c);
请注意,没有引用该方法的类。
{{3}}(已经由@Lawence指出)可能会给你一些见解。我建议你完全阅读。
答案 2 :(得分:0)
Java始终通过完全限定名称来区分其语言元素。
假设您在类myMethod(int a, int b)
中有一个方法MyClass
,它位于包com.mypackage
中,那么java将识别名为com.mypackage.MyClass.myMethod(int a , int b)
的方法。
为了给你更多的见解,当需要解析两个相同的元素时,还需要考虑类加载器。
它确实考虑了哪个类加载器用于加载包含您引用的方法的特定类。 java中有四种类加载器。您可以阅读java.lang.Thread
类的文档。
答案 3 :(得分:0)
1)如何在内部更有效地识别方法?
内部到底是什么?在许多地方,方法可能需要“内部”“识别”。在字节码编译器,JIT编译器,类加载器/链接器,类文件表示,反射API,调试器等。他们每个人都有不同的效率问题。
2)我听说过“方法ID”。这是否意味着上述三元组和整数之间存在映射,因此JVM在解析后仅使用方法ID?
方法id在类文件表示中使用,并且可以由基于它的任何东西使用,包括类加载器/链接器,JIT编译器和调试器。
JVM不解析Java代码。
3)如果是,它是否位于符号表中?
可能会这样做。这取决于“符号表”的含义。请记住,在课程的整个生命周期中,有许多地方需要进行方法识别。例如,Java反射API需要方法信息来实现getDeclaredMethod(...)
等方法和Method
的各种方法。