Java Reflection Use Enzyklopädie

Vorwort

Ich habe mir Javavor vielen Jahren Notizen zum Thema Reflexion gemacht. Nach all den Jahren, in denen ich Reflexion verwende, lese ich nur noch dieses.
Da es jedoch umständlich ist, Notizen in Form von Dateien zu speichern, habe ich sie abgelegt CSDNund hoffe, damit mehr Freunden helfen zu können.

Klasse Klasse

JavaJede Klasse im Programm gehört zur gleichen Art von Dingen, und der Klassenname, Javader diese Art von Dingen beschreibt , lautetJavaClass

Person -> Person
Java-Klasse -> Klasse

Rufen Sie das Instanzobjekt ab, das jedem Bytecode entspricht

Methode 1: Klassenname:class

Class cls1 = Person.class;

Methode 2: Objekt:getClass

Class cls2 = p1.getClass();

Methode drei:forName

Class cls3 = Class.forName("java.lang.String");

Methode vier:getClassLoader().getClass

 Class clazz = getClassLoader().getClass("java.lang.String");

Der Unterschied zwischen .class(), getClass(), Class.forName(), getClassLoader()

.classist die Klasse beim Abrufen der Deklaration.
getClass()ist die Klasse, die die Laufzeit erhält.
Class.forName()Die Klasse wird über den Klassennamen ermittelt.
getClassLoader()ist der Loader, der die Klasse erhält.

Wenn der Bytecode zuvor geladen wurde, befindet er sich bereits in Javader virtuellen Maschine und Sie können direkt zurückkehren, z. B. Methode 1 und Methode 2.
Wenn Javader Bytecode nicht in der virtuellen Maschine vorhanden ist, laden Sie ihn mit dem Klassenlader Der Bytecode wird in der virtuellen Maschine zwischengespeichert. In Zukunft muss dieser Bytecode nicht mehr geladen werden, z. B. bei Methode 3

vordefiniertes Objekt

Es gibt 9vordefinierte Objekte, 8primitive Typen undvoid

Class class1 = boolean.class;
Class class2 = int.class;
//.......
Class class3 = Void.class;

Verwenden Sie diese Option isPrimitive, um zu beurteilen, ob es sich um einen Basistyp handelt

int.class.isPrimitive

Verwenden Sie diese Option isArray, um zu beurteilen, ob es sich um ein Array handelt

int[].class.isArray

Typ abrufen

getclass().getName();

Betrachtung

Bei der Reflexion werden Javaverschiedene Komponenten in einer Klasse den entsprechenden JavaKlassen zugeordnet

Field:Membervariable
Method:Methode
Constructor:Konstruktor
Package:Paket

Konstrukteur

Holen Sie sich alle Konstruktoren einer Klasse

Class.forName("java.lang.String").getConstructors();

Holen Sie sich einen Konstruktor

Geben Sie den entsprechenden Konstruktor gemäß den Parametern in getConstructor zurück

Class.forName("java.lang.String").getConstructor(StringBuffer.class);

Was kann ein Konstrukteur tun?

Holen Sie sich das Instanzobjekt (man constructorkann newunzählige Instanzobjekte erzeugen)

(强制转换)constructor1.newInstance(参数要和getConstructor中的一致);

Erstellen Sie eine Instanz mit der Standardkonstruktionsmethode (die Instanz wird intern zwischengespeichert und beim zweiten Erwerb nicht erneut erstellt, sondern direkt erfasst).

String obj = (String) Class.frName("java.lang.String").newInstance();

Der ursprüngliche Reflexionsschritt besteht darin, Class -> Constructor -> newInstanceihn Class.newInstance()direkt im Inneren zu verwenden Constructor, dh Class -> Class.newInstance()Sie können die Instanz des Standardkonstruktors direkt abrufen

Feld

Stellt eine Mitgliedsvariable in einer Klasse dar

Personenklasse

public class Person {
    
    
    public String name;

    private int age;

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }
}

Erhalten Sie Mitgliedsvariablen durch Reflexion

Person person = new Person();
person.setAge(20);
person.name = "Heiko";
//Field fieldName = person.getClass().getField("name"); 都可以
Field fieldName = Class.forName("reflectTest.Person").getField("name");
//fieldName的值为多少?不是Heiko,因为fieldName不是对象身上的变量,而是类上,要通过field.get("实例")或getDeclaredField来获取该实例上的值
String name = (String) fieldName.get(person);
System.out.println("name:" + name);

//对于私有变量,需暴力破解
Field fieldAge = person.getClass().getDeclaredField("age"); //getDeclaredField 不管是私有还是public的,都可以获取
fieldAge.setAccessible(true); //设置可以访问 fieldAge.get("age")
int age = (int) fieldAge.get(person);
System.out.println("age:" + age);  

Holen Sie sich eine statische Variable

Field filed = obj.getClass().getField(cmdFieldName);
Integer cmdValue = (Integer) filed.get(null); //获取静态变量

Holen Sie sich alle Mitgliedsvariablen

obj.getClass().getFields();

Der Unterschied zwischen getFields und getDeclaredFields

getFields()
getDeclaredFields(): Kann nur auf die in der Klasse als öffentlich deklarierten Felder zugreifen, auf private Felder kann nicht zugegriffen werden, aber auf öffentliche Methoden, die von anderen Klassen geerbt wurden: Kann auf alle Felder in der Klasse zugreifen, unabhängig von der Beziehung, nicht auf Methoden zugreifen, die von anderen Klassen public,private,protectgeerbt wurden

Vergleichen Sie Mitgliedsvariablentypen

if(field.getType() == String.class)

Einstellungen

field.set(obj,新的值);

Ersetzen Sie das b des Mitgliedsvariablenwerts vom Typ String in der Instanz durch a

//将对象中的String类型的成员变量所有的字符b换为字符a
private static void exchangeCharValue(Object obj) throws Exception {
    
    
    Field[] fields = obj.getClass().getFields();
    for(Field field : fields){
    
    
		//if(field.getType().equals(String.class)){ 
        if(field.getType() == String.class){
    
     //这里用 == 比equals更准确,字节码只有一份自己和自己比较
            String oldValue = (String)field.get(obj);
            String newValue = oldValue.replace('b', 'a');
            field.set(obj, newValue);
        }
    }
}

Methode

Stellt eine Mitgliedsmethode in einer Klasse dar

method.invoke(owner, args)
  • owner: Das Objekt, das diese Methode ausführt, args: Parameter, der wie folgt verstanden werden kann: Die Methodenmethode mit Parameter args im Besitzerobjekt.
  • Der Rückgabewert ist Object, was auch der Rückgabewert dieser Methode ist.
String s = "abc";  
Method methodCharAt = String.class.getMethod("charAt", int.class);
String newString =methodCharAt.invoke(s, 1);//invoke是方法身上的方法,s是执行该方法的对象(必须是实例化的对象)
System.out.println(newString); 

Rufen Sie die statische Methode auf

methodCharAt.invoke(null,);

Reflexionsarray

  • Wenn die Abmessungen des Arrays (eindimensional, zweidimensional usw.) und der Array-Typ gleich sind, sind ihre Bytecodes gleich
  • Die übergeordnete Klasse, die von der getSuperClass()-Methode des das Array darstellenden Klasseninstanzobjekts zurückgegeben wird, ist die Klasse, die der Objektklasse entspricht
  • Ein eindimensionales Array von Basistypen kann als Objekttyp verwendet werden, jedoch nicht als Objekt[]-Typ
  • Eindimensionale Arrays von Nicht-Basistypen können als Object-Typen oder als Object[]-Typen verwendet werden

Der Unterschied zwischen int[] und String[] bei ArrayList.asList

Da es den Typ asListempfängt , es sich jedoch nicht um den Typ handelt, wird es für die nachfolgende Verarbeitung als Objekt behandeltObject[]int[]Object[]jdk1.5asList(T...t)int[]

Arrays.asList(new int[]{
    
    1,2,3}); //打印内容为:[@hascode]
Arrays.asList(new String[]{
    
    "1","2","3"}); //打印内容为:[1,2,3]

Array-Reflektionsanwendung

Ausgabearray

private static void printObject(Object obj) {
    
    
    Class clazz = obj.getClass();
    if (clazz.isArray()) {
    
     //如果是数组
        int len = Array.getLength(obj);
        for (int i = 0; i < len; i++) {
    
    
            System.out.println(Array.get(obj, i));
        }
    } else {
    
    
        System.out.println(obj);
    }
}  

überweisen

String[] array = new String[] {
    
     "1", "2", "3" };
String valueString = "test";
printObject(array);
printObject(valueString);

Guess you like

Origin blog.csdn.net/EthanCo/article/details/131121370