代码之家  ›  专栏  ›  技术社区  ›  Nick Holt

更改构造函数参数类型会破坏另一个jar中的类

  •  3
  • Nick Holt  · 技术社区  · 17 年前

    我在一个普通的jar中有以下类:

    public class Common 
    {
      public Common(List list)
      {
        ...  
      }  
    }
    

    然后,我将构造函数参数从 List Collection

    public class Common 
    {
      public Common(Collection collection)
      {
        ...
      }
    }
    

    NoSuchMethodError 在任何依赖类中调用构造函数,直到我重新编译该类。

    我有一些想法,比如构造函数是如何绑定在依赖类的字节码中的,但我不是100%确定。

    请问有人能解释一下这里发生了什么吗?

    随后,我做了一个快速测试,并查看了字节码:

    Compiled from "Client.java"
    public class Client extends java.lang.Object{
    public Client();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   return
    
    public static void main(java.lang.String[]);
      Code:
       0:   new #2; //class ArrayList
       3:   dup
       4:   invokespecial   #3; //Method java/util/ArrayList."<init>":()V
       7:   astore_1
       8:   new #4; //class Common
       11:  dup
       12:  aload_1
       13:  invokespecial   #5; //Method Common."<init>":(Ljava/util/List;)V
       16:  pop
       17:  return
    
    }
    

    3 回复  |  直到 17 年前
        1
  •  5
  •   Michael Myers KitsuneYMG    17 年前

    javac精确地解析在编译时调用哪个方法或构造函数。这在链接时不会发生。由于构造函数签名已更改,链接步骤无法找到请求的方法,因此抛出错误。您可以通过向构造函数提供一个接受 Collection 另一个 List .后来一个构造函数采取 Iterable 可以添加。

    有一个 nice big section in the JLS 准确定义二进制兼容更改的构成。

        2
  •  0
  •   matt b    17 年前

    您是否导入了正确的List和Collection类?也就是 java.util.List java.util.Collection ?

        3
  •  -1
  •   Freddy    17 年前

    我认为这可能是库版本的问题。您确定在同一上下文中的其他地方没有其他版本的commons库吗?