使用Java中的默认构造函数扩展类

时间:2015-11-03 05:43:13

标签: java inheritance access-control

我需要扩展class A,但它需要覆盖它的构造函数。

package com.example.io; // Package belongs to jar from maven dependency

public class A {
    A(String s, Integer i) {
        // constructor code
    }

    // other methods
}

由于它是默认构造函数(仅具有包访问权限的构造函数),因此无法在包外部访问,因此我在源代码com.example.io和扩展class A中创建了相同的包名并成功构建。< / p>

package com.example.io; // Package belongs to my source code

public class B extends A{
    B(String s, Integer i) {
        super(s, i); // Throws error on runtime
    }

    // other methods
}

但是它会抛出运行时错误 -

java.lang.IllegalAccessError: tried to access method com.example.io.A.<init>(Ljava/lang/String;Ljava/lang/Integer;)V from class com.example.io.B

我该如何解决这个问题?我的意思是,有什么方法可以用默认构造函数扩展A类?

2 个答案:

答案 0 :(得分:1)

你绝对不应该只复制第三方图书馆包的名称。这可能会导致意外结果。请参阅this answer

相反,如果类是public,您应该创建自己的子类并定义自己的构造函数。如果超类的构造函数设置为package,则无法调用它。在这种情况下,如果您有代码,则可以根据需要重新实现必要的构造函数:

public class MyClass extends A {

    String myString;
    Integer myInteger;
    String myField;

    MyClass(String s, Integer i) {
        // Can't do this because it's set to package
        // super(s, i);
        // Re-implement?
        this.myString = s;
        this.myInteger = i;
        // Implement your own stuff
        this.myField = s + String.valueOf(i);
    }
}

答案 1 :(得分:-1)

您可以使用反射:

    Constructor<A> constructor = A.class.getDeclaredConstructor(String.class, Integer.class);
    constructor.setAccessible(true);

事实上,我认为通过将包更改为与第三方库相同,它不会起作用。请参阅:Possible to use two java classes with same name and same package?