Class java lang reflect invocationtargetexception

Troubleshooting

This section contains examples of problems developers might encounter when using reflection to locate, invoke, or get information about methods.

NoSuchMethodException Due to Type Erasure

The MethodTrouble example illustrates what happens when type erasure is not taken into consideration by code which searches for a particular method in a class.

import java.lang.reflect.Method; public class MethodTrouble  < public void lookup(T t) <>public void find(Integer i) <> public static void main(String. args) < try < String mName = args[0]; Class cArg = Class.forName(args[1]); Classc = ac.getClass(); Method m = c.getDeclaredMethod("m"); // m.setAccessible(true); // solution Object o = m.invoke(ac); // IllegalAccessException // production code should handle these exceptions more gracefully > catch (NoSuchMethodException x) < x.printStackTrace(); >catch (InvocationTargetException x) < x.printStackTrace(); >catch (IllegalAccessException x) < x.printStackTrace(); >> >

The stack trace for the exception thrown follows.

$ java MethodTroubleAgain java.lang.IllegalAccessException: Class MethodTroubleAgain can not access a member of class AnotherClass with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65) at java.lang.reflect.Method.invoke(Method.java:588) at MethodTroubleAgain.main(MethodTroubleAgain.java:15)

Tip: An access restriction exists which prevents reflective invocation of methods which normally would not be accessible via direct invocation. (This includes—but is not limited to— private methods in a separate class and public methods in a separate private class.) However, Method is declared to extend AccessibleObject which provides the ability to suppress this check via AccessibleObject.setAccessible() . If it succeeds, then subsequent invocations of this method object will not fail due to this problem.

IllegalArgumentException from Method.invoke()

Method.invoke() has been retrofitted to be a variable-arity method. This is an enormous convenience, however it can lead to unexpected behavior. The MethodTroubleToo example shows various ways in which Method.invoke() can produce confusing results.

import java.lang.reflect.Method; public class MethodTroubleToo < public void ping() < System.out.format("PONG!%n"); >public static void main(String. args) < try < MethodTroubleToo mtt = new MethodTroubleToo(); Method m = MethodTroubleToo.class.getMethod("ping"); switch(Integer.parseInt(args[0])) < case 0: m.invoke(mtt); // works break; case 1: m.invoke(mtt, null); // works (expect compiler warning) break; case 2: Object arg2 = null; m.invoke(mtt, arg2); // IllegalArgumentException break; case 3: m.invoke(mtt, new Object[0]); // works break; case 4: Object arg4 = new Object[0]; m.invoke(mtt, arg4); // IllegalArgumentException break; default: System.out.format("Test not found%n"); >// production code should handle these exceptions more gracefully > catch (Exception x) < x.printStackTrace(); >> >
$ java MethodTroubleToo 0 PONG!

Since all of the parameters of Method.invoke() are optional except for the first, they can be omitted when the method to be invoked has no parameters.

$ java MethodTroubleToo 1 PONG!

The code in this case generates this compiler warning because null is ambiguous.

$ javac MethodTroubleToo.java MethodTroubleToo.java:16: warning: non-varargs call of varargs method with inexact argument type for last parameter; m.invoke(mtt, null); // works (expect compiler warning) ^ cast to Object for a varargs call cast to Object[] for a non-varargs call and to suppress this warning 1 warning

It is not possible to determine whether null represents an empty array of arguments or a first argument of null .

$ java MethodTroubleToo 2 java.lang.IllegalArgumentException: wrong number of arguments at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at MethodTroubleToo.main(MethodTroubleToo.java:21)

This fails despite the fact that the argument is null , because the type is a Object and ping() expects no arguments at all.

$ java MethodTroubleToo 3 PONG!

This works because new Object[0] creates an empty array, and to a varargs method, this is equivalent to not passing any of the optional arguments.

$ java MethodTroubleToo 4 java.lang.IllegalArgumentException: wrong number of arguments at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at MethodTroubleToo.main(MethodTroubleToo.java:28)

Unlike the previous example, if the empty array is stored in an Object , then it is treated as an Object . This fails for the same reason that case 2 fails, ping() does not expect an argument.

Tip: When a method foo(Object. o) is declared the compiler will put all of the arguments passed to foo() in an array of type Object . The implementation of foo() is the same as if it were declared foo(Object[] o) . Understanding this may help avoid the types of problems illustrated above.

InvocationTargetException when Invoked Method Fails

An InvocationTargetException wraps all exceptions (checked and unchecked) produced when a method object is invoked. The MethodTroubleReturns example shows how to retrieve the original exception thrown by the invoked method.

import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class MethodTroubleReturns < private void drinkMe(int liters) < if (liters < 0) throw new IllegalArgumentException("I can't drink a negative amount of liquid"); >public static void main(String. args) < try < MethodTroubleReturns mtr = new MethodTroubleReturns(); Classc = mtr.getClass(); Method m = c.getDeclaredMethod("drinkMe", int.class); m.invoke(mtr, -1); // production code should handle these exceptions more gracefully > catch (InvocationTargetException x) < Throwable cause = x.getCause(); System.err.format("drinkMe() failed: %s%n", cause.getMessage()); >catch (Exception x) < x.printStackTrace(); >> >
$ java MethodTroubleReturns drinkMe() failed: I can't drink a negative amount of liquid

Tip: If an InvocationTargetException is thrown, the method was invoked. Diagnosis of the problem would be the same as if the method was called directly and threw the exception that is retrieved by getCause() . This exception does not indicate a problem with the reflection package or its usage.

Источник

Class java lang reflect invocationtargetexception

InvocationTargetException is a checked exception that wraps an exception thrown by an invoked method or constructor. As of release 1.4, this exception has been retrofitted to conform to the general purpose exception-chaining mechanism. The «target exception» that is provided at construction time and accessed via the getTargetException() method is now known as the cause, and may be accessed via the Throwable.getCause() method, as well as the aforementioned «legacy method.»

Constructor Summary

Method Summary

Methods declared in class java.lang.Throwable

Methods declared in class java.lang.Object

Constructor Detail

InvocationTargetException

protected InvocationTargetException()

InvocationTargetException

InvocationTargetException

Method Detail

getTargetException

Get the thrown target exception. This method predates the general-purpose exception chaining facility. The Throwable.getCause() method is now the preferred means of obtaining this information.

getCause

Report a bug or suggest an enhancement
For further API reference and developer documentation see the Java SE Documentation, which contains more detailed, developer-targeted descriptions with conceptual overviews, definitions of terms, workarounds, and working code examples.
Java is a trademark or registered trademark of Oracle and/or its affiliates in the US and other countries.
Copyright © 1993, 2023, Oracle and/or its affiliates, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
All rights reserved. Use is subject to license terms and the documentation redistribution policy.

Источник

Что вызывает java.lang.reflect.Исключение InvocationTargetException?

Узнайте, что вызывает java.lang.reflect.Исключение InvocationTargetException.

1. Обзор

При работе с Java Reflection API часто встречается java.lang.reflect.InvocationTargetException . В этом уроке мы рассмотрим его и то, как с ним справиться, на простом примере .

2. Причина исключения InvocationTargetException

В основном это происходит, когда мы работаем со слоем отражения и пытаемся вызвать метод или конструктор, который сам создает базовое исключение.

Слой отражения обертывает фактическое исключение, вызванное методом, с помощью исключения InvocationTargetException . Давайте попробуем понять это на примере.

Давайте напишем класс с методом, который намеренно создает исключение:

public class InvocationTargetExample < public int divideByZeroExample() < return 1 / 0; >>

Теперь давайте вызовем описанный выше метод, используя отражение в простом тесте JUnit 5:

InvocationTargetExample targetExample = new InvocationTargetExample(); Method method = InvocationTargetExample.class.getMethod("divideByZeroExample"); Exception exception = assertThrows(InvocationTargetException.class, () -> method.invoke(targetExample));

В приведенном выше коде мы утвердили исключение InvocationTargetException , которое возникает при вызове метода. Здесь важно отметить, что фактическое исключение – ArithmeticException в данном случае – оборачивается в InvocationTargetException.

Теперь вопрос, который приходит на ум, заключается в том, почему отражение не создает фактическое исключение в первую очередь?

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

3. Как обрабатывать исключение InvocationTargetException?

Здесь фактическое базовое исключение является причиной InvocationTargetException , поэтому мы можем использовать Throwable.getCause () , чтобы получить дополнительную информацию об этом.

Давайте посмотрим, как мы можем использовать getCause() для получения фактического исключения в том же примере, который использовался выше:

assertEquals(ArithmeticException.class, exception.getCause().getClass());

Здесь мы использовали метод getCause() для того же объекта exception , который был брошен. И мы утверждали ArithmeticException.class как причина исключения.

Таким образом, как только мы получим базовое исключение, мы можем перестроить его, обернуть в какое-то пользовательское исключение или просто зарегистрировать исключение в соответствии с нашими требованиями.

4. Заключение

В этой короткой статье мы рассмотрели, как слой отражения обертывает любое базовое исключение. Мы также видели, как определить основную причину исключения InvocationTargetException и как справиться с таким сценарием на простом примере.

Как обычно, код, используемый в этой статье, доступен на GitHub .

Читайте ещё по теме:

Источник

Читайте также:  Javascript поменять строки таблицы местами
Оцените статью