Jvm Java:为什么.class文件中的方法类型包含返回类型,而不仅仅是签名?

Jvm Java:为什么.class文件中的方法类型包含返回类型,而不仅仅是签名?,jvm,java,Jvm,Java,在.class文件的常量池中有一个“NameAndType”结构。 它用于动态绑定。 该类可以“导出”的所有方法都被描述为“签名+返回类型”。 像 “getVector()Ljava/util/Vector;” 当some.jar中方法的返回类型发生更改时,即使新类型更窄,这也会破坏我的代码 i、 e: 我有以下代码: List l = some.getList(); List l=some.getList(); jar包含: public List getList() 公共列表getList(

在.class文件的常量池中有一个“NameAndType”结构。 它用于动态绑定。 该类可以“导出”的所有方法都被描述为“签名+返回类型”。 像

“getVector()Ljava/util/Vector;” 当some.jar中方法的返回类型发生更改时,即使新类型更窄,这也会破坏我的代码

i、 e: 我有以下代码:

List l = some.getList(); List l=some.getList(); jar包含:

public List getList() 公共列表getList() 外部jar将方法签名更改为

public ArrayList getList(). public ArrayList getList()。 我的代码在运行时会死掉,没有任何方法异常,因为它找不到

getList()Ljava/util/List; getList()Ljava/util/List; 因此,我必须重新编译我的代码。 我不必改变它。只需重新编译完全相同的代码

这也使我们能够拥有两个具有一个签名但返回类型不同的方法!编译器不会接受它,但可以通过直接操作码来实现

我的问题是为什么? 他们为什么这么做

我只有一个想法:防止在运行时进行复杂的类型检查。 您需要查找层次结构,并检查是否存在具有列表界面的父级。 这需要时间,而且只有编译器有时间。JVM没有

我说得对吗


谢谢。

一个原因可能是因为方法重载(与重写相反)是在编译时确定的。考虑以下方法:

public void doSomething(List util) {}

public void doSomething(ArrayList util) {}

并考虑代码:

doSomething(getList());
如果Java允许更改返回类型并且没有抛出异常,那么在重新编译之前,调用的方法仍然是doSomething(List),然后它将是doSomething(ArrayList)。这意味着工作代码会因为重新编译而改变行为

doSomething(getList());