Java方法的内部标识是什么?

6

众所周知,在Java中,方法名不足以区分不同的方法。

我认为(可能是错误的),要区分一个方法,需要以下信息:

(className, methodName, methodParameters)

此外,

  • 如何更有效地内部识别方法?
  • 我听说过“方法ID”。这是否意味着上述三元组和整数之间存在映射,因此JVM在解析后仅使用方法ID?
  • 如果是这样,它是否驻留在符号表中?

谢谢!


1
你的问题太模糊了。你是在说如何在编译器中识别方法吗?还是在".class"文件中?或者是在执行程序中? - Stephen C
4个回答

7

0

Java总是通过它们的完全限定名称来区分其语言元素。

假设你在包com.mypackage中有一个名为MyClass的类,其中有一个方法myMethod(int a, int b),那么Java将使用名称com.mypackage.MyClass.myMethod(int a , int b)来识别该方法。

为了让你更加了解,当需要解析两个相同的元素时,Java还会考虑类加载器。

它确实会考虑用于加载包含你所引用的方法的类的类加载器。Java中有四种类型的类加载器。你可以阅读java.lang.Thread类的文档来了解这些。


1
“在Java中有四种类型的类加载器”是什么意思? - Mike Samuel
被JVM加载的类可以被以下四个类加载器之一加载:1)引导类加载器 2)扩展类加载器 3)系统类加载器 4)应用程序类加载器请注意它们各自的重要性。有关详细信息,请参见下面的链接。 http://javapapers.com/core-java/java-class-loader/ - dharam
啊,好的。 (4) 不像其他的那样被限制,前三个只是通过系统属性约定来区分指定搜索路径。这与线程或方法查找有什么关系呢?该方法基于类,因此间接地取决于类加载器,但提到类加载器的一个分类如何回答原始问题呢? - Mike Samuel
对于具有相似签名的不同方法,我们需要使用完全限定的类名,并且这些类间接依赖于类加载器。在IBM Websphere 6.0.1上经常出现这个问题,如果我们放置两个JAR文件common-collections.3.2.jar和commons.collections.2.0.jar,则无法区分这两个JAR文件中SetUtil类中的某些方法。在这种情况下,我们需要通常定义两个JAR文件的加载策略。 - dharam

0
1) 如何更有效地在内部识别方法?
内部指什么?一个方法可能需要在许多地方“内部”进行“识别”。例如,在字节码编译器、JIT编译器、类加载器/链接器、类文件表示、反射API、调试器等。它们各自具有不同的效率问题。
2) 我听说过“方法ID”。这是否意味着上述三元组与整数之间存在映射,因此JVM在解析后仅使用方法ID?
方法ID在类文件表示中使用,并且可以被基于此的任何东西使用,包括类加载器/链接器、JIT编译器和调试器。
JVM不解析Java代码。
3) 如果是这样,它是否驻留在符号表中?
可能是这样。这取决于您对“符号表”的理解。请记住,在类的整个生命周期中都需要方法标识。例如,Java反射API需要方法信息来实现诸如getDeclaredMethod(...)和Method的各种方法。

0

我不是很明白你想做什么,但我认为仍然有一些可能的答案:

  • 您可能会对JNI方法描述符感兴趣,这是JVM(以及JNI库)内部使用的各种字符串格式之一,用于识别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类提供接收int并来自类String的方法charAt
换句话说,您的标识元组几乎正确 - 它只是没有类:
(methodName, methodParameters)

相比于从JVM检索方法并传递类、方法名称和参数类型,您可以直接从类中检索方法,给出类名和参数类型即可。这是微妙的差别,但我认为这就是您想知道的。

即使在我下面提到的JNI描述符中也可以看出这一点。例如,该方法

long f(int i, Class c);

由以下描述符表示:

"(ILjava/lang/Class;)J"

请注意,该方法的类别没有任何参考。 关于类文件格式的优秀文档(已由@Lawence指出)可能会给您一些启示。我建议您完整阅读它。

我怀疑JVM内部没有这样的表格。JVM可以为内部使用定义这样的表格,但这样做可能会使类加载器的垃圾回收变得复杂。 - Mike Samuel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接