Статьи

Учебник по отражению Java

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

Что такое отражение?

Вкратце, отражение — это способность программы исследовать и изменять структуру и поведение объекта во время выполнения.

Эта концепция иногда смешивается с самоанализом. Самоанализ (интроспекция типа) — это способность программы проверять тип или свойства объекта во время выполнения. Следовательно, это подмножество размышлений. Некоторые языки поддерживают интроспекцию, но не поддерживают рефлексию, например, C ++.

Зачем нам нужно размышление?

Отражение позволяет нам сделать следующее:

  • Изучите класс объекта во время выполнения
  • Создайте объект для класса во время выполнения
  • Изучите поле и метод класса во время выполнения
  • Вызвать любой метод объекта во время выполнения

Например, JUnit использует отражение для просмотра методов, помеченных аннотацией @Test , а затем вызывает эти методы при запуске модульного теста. (Вот несколько примеров того, как использовать JUnit .)

Пример 1: Получить имя класса из объекта

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
package myreflection;
import java.lang.reflect.Method;
 
public class ReflectionHelloWorld {
    public static void main(String[] args){
        Foo f = new Foo();
        System.out.println(f.getClass().getName());        
    }
}
 
class Foo {
    public void print() {
        System.out.println("abc");
    }
}

Выход:

1
myreflection.Foo

Пример 2: вызов метода для неизвестного объекта

Для приведенного ниже примера кода тип изображения объекта неизвестен. Используя отражение, код может использовать объект и выяснить, есть ли у объекта метод с именем «print», а затем вызвать его.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
package myreflection;
import java.lang.reflect.Method;
 
public class ReflectionHelloWorld {
    public static void main(String[] args){
        Foo f = new Foo();
 
        Method method;
        try {
            method = f.getClass().getMethod("print", new Class<?>[0]);
            method.invoke(f);
        } catch (Exception e) {
            e.printStackTrace();
        }          
    }
}
 
class Foo {
    public void print() {
        System.out.println("abc");
    }
}
1
abc

Пример 3: создание объекта из экземпляра класса

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package myreflection;
 
public class ReflectionHelloWorld {
    public static void main(String[] args){
        //create instance of "Class"
        Class<?> c = null;
        try{
            c=Class.forName("myreflection.Foo");
        }catch(Exception e){
            e.printStackTrace();
        }
 
        //create instance of "Foo"
        Foo f = null;
 
        try {
            f = (Foo) c.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }  
 
        f.print();
    }
}
 
class Foo {
    public void print() {
        System.out.println("abc");
    }
}

Пример 4: Получить конструктор и создать экземпляр

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package myreflection;
 
import java.lang.reflect.Constructor;
 
public class ReflectionHelloWorld {
    public static void main(String[] args){
        //create instance of "Class"
        Class<?> c = null;
        try{
            c=Class.forName("myreflection.Foo");
        }catch(Exception e){
            e.printStackTrace();
        }
 
        //create instance of "Foo"
        Foo f1 = null;
        Foo f2 = null;
 
        //get all constructors
        Constructor<?> cons[] = c.getConstructors();
 
        try {
            f1 = (Foo) cons[0].newInstance();
            f2 = (Foo) cons[1].newInstance("abc");
        } catch (Exception e) {
            e.printStackTrace();
        }  
 
        f1.print();
        f2.print();
    }
}
 
class Foo {
    String s;
 
    public Foo(){}
 
    public Foo(String s){
        this.s=s;
    }
 
    public void print() {
        System.out.println(s);
    }
}

Выход:

1
2
3
null
 
abc

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

Пример 5: изменение размера массива через отражение

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package myreflection;
 
import java.lang.reflect.Array;
 
public class ReflectionHelloWorld {
    public static void main(String[] args) {
        int[] intArray = { 1, 2, 3, 4, 5 };
        int[] newIntArray = (int[]) changeArraySize(intArray, 10);
        print(newIntArray);
 
        String[] atr = { "a", "b", "c", "d", "e" };
        String[] str1 = (String[]) changeArraySize(atr, 10);
        print(str1);
    }
 
    // change array size
    public static Object changeArraySize(Object obj, int len) {
        Class<?> arr = obj.getClass().getComponentType();
        Object newArray = Array.newInstance(arr, len);
 
        //do array copy
        int co = Array.getLength(obj);
        System.arraycopy(obj, 0, newArray, 0, co);
        return newArray;
    }
 
    // print
    public static void print(Object obj) {
        Class<?> c = obj.getClass();
        if (!c.isArray()) {
            return;
        }
 
        System.out.println("\nArray length: " + Array.getLength(obj));
 
        for (int i = 0; i < Array.getLength(obj); i++) {
            System.out.print(Array.get(obj, i) + " ");
        }
    }
}

Выход:

1
2
3
4
Array length: 10
1 2 3 4 5 0 0 0 0 0
Array length: 10
a b c d e null null null null null

Резюме

Приведенные выше примеры кода показывают очень маленький набор функций, предоставляемых Java-отражением. Чтение этих примеров может только дать вам представление о Java, вы можете прочитать дополнительную информацию на веб-сайте Oracle .

Ссылка: учебник по отражению Java от нашего партнера по JCG Сяорана Вана в блоге Programcreek .