Invokespecial Verify Error: тип не может быть назначен

После этой строки:

qty = scan.nextInt();

Всегда добавляйте еще одну строку для очистки сканера:

scan.nextLine();

Кроме того, используйте

sc.nextLine();

вместо

sc.next();
5
задан Naman 11 March 2019 в 15:57
поделиться

2 ответа

Вы пытаетесь выполнить invokespecial на экземпляре Type (возвращаемом invokevirtual @ 9), в то время как верификатор ожидает ссылку на текущий класс, т.е. Type$ClassType.

См. JVMS §4.10.1.9 :

Можно корректно заменить типы, соответствующие текущему классу , и типы аргументов, приведенные в дескрипторе для входящего стек операндов с возвращаемым типом, заданным в дескрипторе, с выходным состоянием типа.

0
ответ дан apangin 11 March 2019 в 15:57
поделиться

invokespecial используется для реализации любой из трех вещей

  1. Вызов конструктора
  2. Вызов метода private
  3. Выполнение вызова super. …

Хотя 1. здесь не применяется (поскольку имя целевого метода не <init>), в любом из других случаев требуется, чтобы тип получателя был текущего класса или его подкласса. Таким образом, даже когда класс объявления метода равен Type, ожидается, что фактический тип получателя будет назначаться текущему классу, Type$ClassType.

Ближайшим эквивалентом того, что вы создали со своим изменением, является вызов super, хотя в исходном коде Java вызов метода через super заставляет ссылку на приемник быть такой же, как this, что присваивается текущему классу.

На уровне байт-кода правила менее ограничительны, тем не менее, вызов метода, позволяющий обходить объявления методов в вашем текущем классе или его подклассах, не разрешается вызывать для ссылки на тип, которая может указывать на экземпляр полностью несвязанная иерархия подклассов, то есть Type не является Type$ClassType.

Соответствующее правило JVMS уже упоминалось в ответе Апангина .

0
ответ дан Holger 11 March 2019 в 15:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: