|
Spec-Zone .ru
спецификации, руководства, описания, API
|
Отражение обеспечивает средство для того, чтобы оно вызвало методы на class. Как правило, это только было бы необходимо, если не возможно бросить экземпляр class к требуемому, вводят неотражающий код. Методы вызываются с java.lang.reflect.Method.invoke(). Первым параметром является объектный экземпляр, на который должен быть вызван этот определенный метод. (Если метод static, первый параметр должен быть null.) Последующими параметрами являются параметры метода. Если базовый метод выдаст исключение, то он будет обернут . Исходное исключение метода может быть получено, используя исключение, объединяющее механизм в цепочку метод.
Рассмотрите тестовый комплект, который использует отражение, чтобы вызвать частные методы испытаний в данном class. параметр. Это тогда вызывает каждый метод соответствия.
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Locale;
import static java.lang.System.out;
import static java.lang.System.err;
public class Deet<T> {
private boolean testDeet(Locale l) {
// getISO3Language() may throw a MissingResourceException
out.format("Locale = %s, ISO Language Code = %s%n", l.getDisplayName(), l.getISO3Language());
return true;
}
private int testFoo(Locale l) { return 0; }
private boolean testBar() { return true; }
public static void main(String... args) {
if (args.length != 4) {
err.format("Usage: java Deet <classname> <langauge> <country> <variant>%n");
return;
}
try {
Class<?> c = Class.forName(args[0]);
Object t = c.newInstance();
Method[] allMethods = c.getDeclaredMethods();
for (Method m : allMethods) {
String mname = m.getName();
if (!mname.startsWith("test")
|| (m.getGenericReturnType() != boolean.class)) {
continue;
}
Type[] pType = m.getGenericParameterTypes();
if ((pType.length != 1)
|| Locale.class.isAssignableFrom(pType[0].getClass())) {
continue;
}
out.format("invoking %s()%n", mname);
try {
m.setAccessible(true);
Object o = m.invoke(t, new Locale(args[1], args[2], args[3]));
out.format("%s() returned %b%n", mname, (Boolean) o);
// Handle any exceptions thrown by method to be invoked.
} catch (InvocationTargetException x) {
Throwable cause = x.getCause();
err.format("invocation of %s failed: %s%n",
mname, cause.getMessage());
}
}
// production code should handle these exceptions more gracefully
} catch (ClassNotFoundException x) {
x.printStackTrace();
} catch (InstantiationException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
}
}
}
Deet вызывает который возвратит все методы, явно объявленные в class. Кроме того, используется, чтобы определить, являются ли параметры расположенного метода совместимыми с требуемым вызовом. Технически код, возможно, протестировал, является ли следующий оператор true с тех пор final:
Locale.class == pType[0].getClass()
Однако, является более общим.
$ java Deet Deet ja JP JP invoking testDeet() Locale = Japanese (Japan,JP), ISO Language Code = jpn testDeet() returned true
$ java Deet Deet xx XX XX invoking testDeet() invocation of testDeet failed: Couldn't find 3-letter language code for xx
Во-первых, отметьте это только testDeet() встречает ограничения объявления, осуществленные кодом. Затем, когда testDeet() передается несостоятельный довод, он бросает непроверенное . В отражении нет никакого различия в обработке проверенных против исключений непроверенных. Они все обертываются в
может использоваться, чтобы передать переменное число параметров методу. Ключевое понятие, чтобы понять - то, что методы переменной арности реализуются, как будто переменные параметры упаковываются в массиве.
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
public class InvokeMain {
public static void main(String... args) {
try {
Class<?> c = Class.forName(args[0]);
Class[] argTypes = new Class[] { String[].class };
Method main = c.getDeclaredMethod("main", argTypes);
String[] mainArgs = Arrays.copyOfRange(args, 1, args.length);
System.out.format("invoking %s.main()%n", c.getName());
main.invoke(null, (Object)mainArgs);
// production code should handle these exceptions more gracefully
} catch (ClassNotFoundException x) {
x.printStackTrace();
} catch (NoSuchMethodException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
} catch (InvocationTargetException x) {
x.printStackTrace();
}
}
}
Во-первых, чтобы найти main() метод код ищет class с именем, "основным" с единственным параметром, который является массивом String С тех пор main() static, null первый параметр . Вторым параметром является массив параметров, которые передадут.
$ java InvokeMain Deet Deet ja JP JP invoking Deet.main() invoking testDeet() Locale = Japanese (Japan,JP), ISO Language Code = jpn testDeet() returned true