实例化错误

时间:2013-02-12 19:48:33

标签: java

我正在关注一本初学者的java书籍,其中一个项目是从常常抛出的错误中选择一个错误,并尝试尽你所能来引发错误。

我选择了InstantiationError,并且知道你无法实例化抽象类或接口。文档说错误通常由编译器捕获,但如果类的定义发生不兼容的更改,则可以在运行时抛出错误。

我不知道在程序运行时如何更改类定义,我正在寻找一些关于我应该进一步阅读的提示。 谢谢!

4 个答案:

答案 0 :(得分:8)

  

我不知道在程序运行时如何更改类定义

在运行时无法更改,但在编译后可以更改

例如,试试这个:

// In Test.java
public class Test {
    public static void main(String[] args){
        System.out.println(new Foo());
    }
}

// In Foo.java
public class Foo {
}

编译:

javac Foo.java Test.java

执行命令

java Test

// Some output like this...
Foo@1d6535bf

现在像这样更改Foo.java

// No parameterless constructor any more!
public class Foo {
    public Foo(int x) {
    }
}

重新编译只是 Foo.java

javac Foo.java

重新运行测试:

Exception in thread "main" java.lang.NoSuchMethodError: Foo: method <init>()V 
    not found
    at Test.main(Test.java:3)

这是不是我称之为“常常抛出的错误”。

请注意,这不是InstantiationError - 但您可以再次更改Foo.java,以便:

public interface Foo {
}

再次,重新编译Foo.java,这次你会得到:

Exception in thread "main" java.lang.InstantiationError: Foo
        at Test.main(Test.java:3)

答案 1 :(得分:6)

可能在运行时使用反射实例化一个抽象类。

代码示例:

public abstract class MyAbstractClass{
}

public class MyMainClass() {
    public void test(String[] args) {
             this.getClass().getClassLoader().loadClass("MyAbstractClass").getConstructors()[0].newInstance();
    }
}

答案 2 :(得分:1)

查看Reflection API,它提供了一种按名称实例化类的方法。

public void throwError() {
    AbstractType type = this.getClassLoader().newInstance("my.abstract.Type");
} 

答案 3 :(得分:1)

如果您尝试使用错误数量的参数创建对象,则可能导致此类错误的简单事情。假设构造函数有两个参数,但您的界面设计方式使用户可以输入3个或更多参数。通常,编译器会捕获参数的数量,但如果它是“动态”创建的,那么它将在运行时被捕获