Вот разбивка для всего сообщения:
Caused by: java.lang.VerifyError: Bad return type
Здесь указывается, что является исключением (java.lang.VerifyError
), и сообщением об ошибке, связанным с ним (Bad return type
). Вы можете использовать тип исключения, чтобы определить общее представление о том, что такое исключение (например, если это NullPointerException
, вы можете сказать, что был какой-то нулевой объект, на который была ссылка), но вам нужно использовать исключение сообщение, чтобы лучше понять, почему возникло исключение. Здесь это выглядит так, как будто вы пытались вернуть тип, отличный от типа, указанного в определении метода.
Location:
com/company/MyClass.getProperty(Ljava/lang/String;)Ljava/lang/Object; @93: ireturn
Здесь указывается, где произошло исключение. Вы можете сказать, что это произошло в классе в com.company.MyClass
по методу getProperty
. Он также сообщает вам параметр метода, равный String
, и тип возвращаемого значения, равный Object
. @93: ireturn
относится к байт-коду Java, о котором я расскажу позже.
Reason:
Type integer (current frame, stack[0]) is not assignable to 'java/lang/Object' (from method signature)
Это дает вам более конкретную причину, по которой было сгенерировано исключение, и точно объясняет, почему. Он говорит вам, что целое число нельзя присвоить Object
(возможно, это потому, что вы пытаетесь вернуть примитив int
, который не наследует тип Object
).
Current Frame:
bci: @93
flags: { }
locals: { 'com/company/MyClass', 'java/lang/String', 'java/lang/String' }
stack: { integer }
В этом разделе рассказывается о текущем кадре. Чтобы углубиться в это, мы должны посмотреть, как на самом деле работает Java. Когда вы компилируете некоторый код в Java, он превращает его в байт-код Java. Это похоже на обычную сборку, за исключением того, что она может работать только на JVM или виртуальной машине Java. На этой виртуальной машине создаются frame
и содержат всю локальную информацию. Я не полностью разбираюсь в особенностях этой информации, но, насколько мне известно, тег bci
содержит текущую позицию в байт-коде. locals
сообщает Java, какие классы загружаются в текущую область, а stack
именно так и звучит. В основном это просто список значений.
Bytecode:
0x0000000: 2b01 a600 0812 8da7 0007 2bb6 0090 4d2c
0x0000010: b600 94ab 0000 0064 0000 0007 9a7f 0d13
0x0000020: 0000 005f 9b27 5edf 0000 004b 0000 fc71
0x0000030: 0000 0041 0023 a6ed 0000 005a 03b3 b10f
0x0000040: 0000 0046 34ad f045 0000 0055 7a92 a99e
0x0000050: 0000 0050 2ab6 0096 b02a b600 98ac 2ab6
0x0000060: 009a b02a b600 9cb0 2ab6 009e b02a b600
0x0000070: a0b0 2ab6 00a2 b0bb 0079 59bb 007b 59b7
0x0000080: 007c 12a4 b600 822c b600 82b6 0086 b700
0x0000090: 88bf
Это говорит вам необработанный байт-код вашей программы. Это то, что читается JVM и довольно тесно связано с кодом сборки. Вы можете посмотреть на Bytecode Viewer и увидеть байт-код в более понятной для человека форме.
Stackmap Table:
same_frame(@10)
same_locals_1_stack_item_frame(@14,Object[#101])
append_frame(@84,Object[#101])
same_frame(@89)
same_frame(@94)
same_frame(@99)
same_frame(@104)
same_frame(@109)
same_frame(@114)
same_frame(@119)
Таблица Stackmap, по сути, сообщает Java ожидаемые типы переменных и операндов метода во время его выполнения. Вы можете прочитать больше об этом здесь .
Я надеюсь, что эта информация даст вам хорошее объяснение всего, что вы искали. Не стесняйтесь попросить лучшего объяснения чего-либо.