#java #reflection
#java #отражение
Вопрос:
Итак, вот класс с объявленным внутри частным внутренним классом и частным атрибутом. Мне нужно использовать отражение Java для написания тестовой программы в функции main для выполнения этого класса.
public class Outter {
private Inner in;
public Outter(){
in = new Inner();
}
private class Inner{
private void test(){
System.out.println("test");
}
}
}
Вот тестовый код: мои вопросы перечислены после инструкции.
public class Test
{
public static void main(String[] args) throws Exception
{
// 1. How do i create a Class type for Inner class since its modifier
// is private, if I am going to need .setAccessible() then how do i
// use it?
Class outter1 = Outter.class;
// 2. How do I pass parameters of type Inner to the Class object?
Constructor con = outter1.getConstructor(new Class[]{int.class});
// 3. Like this?
Field fields = outter1.getField("test");
fields.setAccessible(true);
// 4. Well I am lost what is the logic route for me to follow when
// using java reflection to execute a class like this!
Object temp = outter1.newInstance();
Outter outter = (Outter)temp;
System.out.println(fields.get(outter));
}
}
Ответ №1:
Вот автономный пример того, что вы пытаетесь сделать.
Код, который вы запускаете
try {
// gets the "in" field
Field f = Outer.class.getDeclaredField("in");
// sets it accessible as it's private
f.setAccessible(true);
// gets an instance of the Inner class by getting the instance of the
// "in" field from an instance of the Outer class - we know "in" is
// initialized in the no-args constructor
Object o = Object o = f.get(Outer.class.newInstance());
// gets the "execute" method
Method m = o.getClass().getDeclaredMethod("test", (Class<?>[])null);
// sets it accessible to this context
m.setAccessible(true);
// invokes the method
m.invoke(o, (Object[])null);
}
// TODO better handling
catch (Throwable t) {
t.printStackTrace();
}
Классы (внутренние / внешние)…
public class Outer {
private Inner in;
public Outer() {
in = new Inner();
}
private class Inner {
private void test() {
System.out.println("test");
}
}
}
Вывод
test
Комментарии:
1. хотя ваш код правильный ( 1) Я думаю, что ваш ответ должен содержать некоторые пояснения. В противном случае OP не поймет разницы и будет делать те же ошибки в будущем.
2. @AlexR спасибо за ваш комментарий. Я прокомментировал свой код … в каком заявлении, по вашему мнению, я должен уточнить?
3. О, прошу прощения, я не обратил внимания на комментарии внутри кода. Вероятно, полезно объяснить разницу между внутренним классом и 2 классами в одном файле.
4. @AlexR на самом деле я только что понял, что мой ответ может сбить с толку, поскольку я не установил
in
поле как закрытое, что, в свою очередь, изменяет код. Должно быть, потому, что вопрос был не очень хорошо отформатирован. Отредактирует мой ответ. редактирование выполнено.5. прошу прощения, но что-то потеряно во внешнем классе, переменная in модифицируется ключевым словом Private и этот линейный объект o = Outer.class.getDeclaredField(«in»).get(Outer.class.newInstance()); вызывает ошибку, поскольку не удалось получить доступ к частной переменной in .