2016-03-18 2 views
0

Я создал класс для реализации интерфейса и тестировал его с использованием другого класса.Java InstantiationException

Это класс, который я создал.

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; 
} 
} 

Это часть тестера, что я получаю ошибку. Я просто взял часть тестера, чтобы уменьшить объем кода, который я отправлял. Если вам нужен полный тестер, я могу его изменить.

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); 

Когда я запускаю код, я получаю InstatiationException на линии тестера, который начинается с «WeaponI оружием» вблизи дна. Есть два других класса, которые также должны быть переданы тестеру, и я предполагаю, что обе они также будут иметь одинаковую проблему. Я честно понятия не имею, как исправить эту проблему, поэтому любая помощь будет высоко оценена.

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 
+0

Вы должны смотреть на остальной части трассировки стека. Он содержит основное исключение. – EJP

ответ

0

Для работы Class.newInstance для работы ему нужен конструктор по умолчанию. Вы можете добавить конструктор по умолчанию в класс MyWeapon и попробовать.

Цитируя Javadoc для Class

InstantiationException - если этот класс представляет собой абстрактный класс, интерфейса, класс массива, примитивный тип или недействительный; или если класс не имеет нулевого конструктора; или если экземпляр не завершился с ошибкой для другой причиной.

0

Вы делаете следующее:

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

В классе warriorsandweapons.MyWeaponI. Этот класс имеет только один конструктор, и это конструктор, который принимает один аргумент.

Если вы посмотрите на Javadoc for Class.newInstance() вы видите следующее примечание:

конкретизируется класс, как будто новое выражение с пустым списком аргументов .

Таким образом, вы можете использовать только newInstance, если есть конструктор, который не принимает аргументы. На MyWeaponI такого конструктора нет, поэтому вы получаете это исключение.

Вместо этого, вы можете использовать java.lang.reflect.Constructor для создания экземпляра и передать аргументы:

Class<WeaponI> weaponClass; 
// ... 
Constructor<WeaponI> constructor = weaponClass.getConstructor(String.class); 
WeaponI instance = constructor.newInstance(nameArgument); 
Смежные вопросы