简体   繁体   中英

Java InstantiationException

I made a class to implement an interface and was testing it using another class.

This is the class that I created.

public class MyWeaponI implements WeaponI {

Random RAND = new Random();
private int maxDamage;
private String name;

public MyWeaponI(String name1){
    maxDamage = 10;
    name = name1;  
}

@Override
public int getDamage() {
    return RAND.nextInt(maxDamage)+1;
}

@Override
public int getMaxDamage() {
    return maxDamage;
}

@Override
public String toString(){
    return String.format("Weapon %s, damage=%d", name, maxDamage);
}

@Override
public void initFromString(String input) {
    Scanner s = new Scanner(input);
    s.useDelimiter("$n");
    String pattern = "(\\w+)\\s*,\\s*(\\d)\\s*";
    if(s.hasNext(pattern)){
        MatchResult m = s.match();
        maxDamage = Integer.parseInt(m.group(2));
        name = m.group(1);
        System.out.println(String.format("Weapon %s, damage=%d", m.group(1), Integer.parseInt(m.group(2))));
    }
}

@Override
public String getName() {
    return name;
}
}

This is the part of the tester that I get the error in. I just took out part of the tester to reduce the amount of code that I was posting. If you need the full tester I can change it.

Class warriorClass = null, weaponClass = null, diskClass = null;
for(int i=0;i<args.length;i++) {
  Class c = Class.forName(args[i]);
  if(WeaponI.class.isAssignableFrom(c))
    weaponClass = c;
  else if(WarriorI.class.isAssignableFrom(c))
    warriorClass = c;
  else if(DiskI.class.isAssignableFrom(c))
    diskClass = c;
  else
    assert false : "Not a class name: "+args[i];
}

assert weaponClass != null : "You need to supply a weapon class";
WeaponI weapon = (WeaponI)weaponClass.newInstance();
testWeapon(weapon);

When I run the code, I get an InstatiationException on the line of the tester that starts with "WeaponI weapon" near the bottom. There are two other classes that that also need to be passed to the tester and I'm assuming that both of them will also have to same problem. I honestly have no idea how to fix the problem, so any help would be much appreciated.

Exception in thread "main" java.lang.InstantiationException: warriorsandweapons.MyWeaponI
at java.lang.Class.newInstance(Class.java:368)
at warriorsandweapons.Arena.main(Arena.java:308)
Java Result: 1

For Class.newInstance to work it needs a default constructor. You can add a default constructor to MyWeapon class and try.

Quoting from javadoc for Class

InstantiationException - if this Class represents an abstract class, an interface, an array class, a primitive type, or void; or if the class has no nullary constructor; or if the instantiation fails for some other reason.

You're doing the following:

WeaponI weapon = (WeaponI)weaponClass.newInstance();

On class warriorsandweapons.MyWeaponI . This class has only one constructor, and it's a constructor that takes a single argument.

If you look at the Javadoc for Class.newInstance() you see the following note:

The class is instantiated as if by a new expression with an empty argument list.

So you can only use newInstance if there is a constructor that doesn't take arguments. There is no such constructor on MyWeaponI , that's why you get this exception.

Instead, you can use java.lang.reflect.Constructor to create the instance and pass arguments:

Class<WeaponI> weaponClass;
// ... 
Constructor<WeaponI> constructor = weaponClass.getConstructor(String.class);
WeaponI instance = constructor.newInstance(nameArgument);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM