rjones
rjones

Reputation: 83

Instantiation error

I am following a beginner's java book and one of the projects is to pick an error from commonly thrown errors and try to do what you can to induce the error.

I picked InstantiationError and am up to the level of knowing you can't instantiate abstract classes or interfaces. The docs says the error is usually caught by the compiler but can be thrown at runtime if the definition of a class has incompatibly changed.

I don't know how a class definition could be changed while the program is running and am looking for some tips on where I should read further. Thanks!

Upvotes: 8

Views: 10256

Answers (4)

Jeff Hawthorne
Jeff Hawthorne

Reputation: 568

a simple thing that can cause this type of error is if you try to create an object with the wrong number of parameters. say the constructor takes two parameters, but you have your interface designed in such a way that the user could input 3 or more parameters. normally, the number of parameters would be caught by the compiler, but if it was created "on the fly" then it would get caught at runtime

Upvotes: 1

axelrod
axelrod

Reputation: 3978

Maybe when you instantiate an abstract class at runtime using reflection.

Code sample:

public abstract class MyAbstractClass{
}

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

Upvotes: 6

Jon Skeet
Jon Skeet

Reputation: 1500145

I don't know how a class definition could be changed while the program is running

It can't change while it's running but it can change after you've compiled.

For example, try this:

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

// In Foo.java
public class Foo {
}

Compile:

javac Foo.java Test.java

Run:

java Test

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

Now change Foo.java like this:

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

Recompile just Foo.java:

javac Foo.java

And rerun Test:

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

This is not what I'd call a "commonly thrown error" though.

Note that that's not InstantiationError - but you can change Foo.java again, to:

public interface Foo {
}

Again, just recompile Foo.java and this time you'll get:

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

Upvotes: 11

Peter Bratton
Peter Bratton

Reputation: 6408

Have a look at the Reflection API, which offers a way to instantiate a class by name.

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

Upvotes: 1

Related Questions