Play with java reflex

Keywords: Java Android

original text

classloader

  • What is a Class Loader
  • Responsibilities of Class Loaders
  • Composition of Class Loader

reflex

  • What is Reflection
  • How to Use Reflection
  • Application of Reflection in Android

What is a Class Loader
When a Java program wants to use a class, if the class has not been loaded into memory, the system will initialize the class by loading, linking and initializing the three steps.
Load
That is to read the class file into memory and create a Class object for it.
The system creates a Class object when any class is used.
link
Verify that there is a correct internal structure and that it is consistent with other classes.
Prepare to allocate memory for static members of the class and set default initialization values.
Parsing replaces symbolic references in the binary data of a class with direct references.
Initialization
Class initialization without too much description

Class initialization timing (when will it be loaded into memory)

  • Create instances of classes
  • Access static variables of a class to get assignments for static variables
  • Static methods using classes
  • Use reflection to force the creation of a class or interface to correspond to a Class object
  • Initialize a subclass of a class (the parent class is loaded into memory first)
    Use the java.exe command to run a main class

When any of the above conditions are satisfied, the class is initialized

Responsibilities of Class Loaders
It is responsible for loading. class files into memory and generating Class objects.
Composition of Class Loader

  • Bootstrap ClassLoader Root Class Loader (C Code Completion)
    The core class responsible for loading Java runs
    There is rt.jar in the jre/lib directory, which is the core class library compiled by the system. Bootstrap is responsible for loading rt.jar.
  • Extension Class Loader Extension Class Loader (C Code Completion)
    Responsible for loading the application of forehead expansion
    Extended application classes in jre/lib/ext directory

  • System Class Loader System Class Loader (Java Code Completion)
    System ClassLoader is responsible for loading the classes we write

What is Reflection

  • Java reflection mechanism is in the running state, for any class, we can know all the attributes and methods of this class; for any object, we can call any of its methods and attributes; so dynamic acquisition of new and dynamic invocation of object methods is called reflection.
  • Simply put, reflection is dissecting a Class, and then acquiring the attributes and methods in the Class, provided that the Class object is acquired.
  • Several classes are provided in java for describing compiled objects.
    | Class | Description|
    | ------------- |:-------------:|
    | java.lang.Class | Describes the object of the compiled class file|
    | java.lang.reflect.Constructor | for describing construction methods|
    | java.lang.reflect.Field | Description field (member variable)|
    | java.lang.reflect.Method | Describes member methods|

How to Use Reflection
A. Use the Class class to get the class file object of the dissected class
B. Use the Class class method to get all the members in the class
C. After members are obtained, they are handed over to corresponding classes, methods in corresponding classes, and running members.

How to get the class file object

  1. Object acquisition using classes
    Each class uses Object as its parent, and the Object class method getClass()
    Returns the class file object of this class, and the method returns the value Class type object.

  2. Using static attributes of classes to obtain
    Class name. Class returns the class file object of this class. The result of the property operation is also a Class type object.

  3. Using Class Class Class Static Method to Get
    Class class static method forName(String class name) passes string class name

    Gets the class file object of this class, and the method return value is also a Class type object.

No matter which way to get lass objects, they are all equal.

package com.test.demo;
/**
 * Define the person class
 */
public class Person {

}

package com.test.demo;

public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException {

        //The first way to get a Class object

        Person p1=new Person();
        Class cc=p1.getClass();
        System.out.println(cc);

        //The second way to get Class objects
        Class cc2=Person.class;
        System.out.println(cc2);
        //The third way to get Class objects
        Class cc3=Class.forName("com.test.demo.Person");//Full class name
        System.out.println(cc3);

        System.out.println(cc==cc2);
        System.out.println(cc2==cc3);
    }
}


//Output results
class com.test.demo.Person
class com.test.demo.Person
class com.test.demo.Person
true
true

Getting constructs

by Person Class addition structure

public Person(){
        System.out.println("Person Class parametric construction");
    }
    public Person(int a,int b,String s){
        System.out.println("Person Classes have parametric constructs: a:"+a+" b:"+b+" s:"+s);
    }

    private Person(int a){
        System.out.println("Person Class has parameter private constructs: a:"+a);
    }



package com.test.demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

        Class clazz=Person.class;
        //Get all the common constructs of the Person class
        Constructor [] conarr=clazz.getConstructors();

        for(Constructor con :conarr){
            System.out.println(con);
        }
        //Gets the specified constructor
        //No parameters
        Constructor cc=clazz.getConstructor();
        Object oo=cc.newInstance();

        //With parameters
        Constructor cc2=clazz.getConstructor(int.class,int.class,String.class);
        Object oo2=cc2.newInstance(1,2,"haha");

        //Getting Private Construction Method
        Constructor cc3=clazz.getDeclaredConstructor(int.class);
        //Violent visits
        cc3.setAccessible(true);
        Object oo3=cc3.newInstance(1);

        clazz.newInstance();//To directly obtain null parameter construction, it must be public.
    }
}

//Output results
public com.test.demo.Person()
public com.test.demo.Person(int,int,java.lang.String)
Person Class parametric construction
Person Classes have parametric constructs: a:1 b:2 s:haha
Person Class has parameter private constructs: a:1
Person Class parametric construction

Get member variables

by Person Class adds member variables

    public String name="smt";
    private String idcard="1001u09t";

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "name:"+name+"  idcard:"+idcard;
    }

package com.test.demo;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException,
            NoSuchMethodException, SecurityException, InstantiationException,
            IllegalAccessException, IllegalArgumentException,
            InvocationTargetException, NoSuchFieldException {

        Class clazz = Person.class;
        Object obj = clazz.newInstance();
        // Get all public member variables of the Person class
        Field[] fields = clazz.getFields();
        for(Field s:fields){
            System.out.println(s);
        }

        Field field=clazz.getField("name");

        field.set(obj, "haha");

        System.out.println(obj);

        Field field2=clazz.getDeclaredField("idcard");
        field2.setAccessible(true);
        field2.set(obj, "123456");
        System.out.println(obj);
    }
}

//Output results
Person Class parametric construction
public java.lang.String com.test.demo.Person.name
name:haha  idcard:1001u09t
name:haha  idcard:123456

Getting membership methods

    by Person Class Increase Membership Method

    public void show(){
        System.out.println("show Empty parameter");
    }
    public void show(int a){
        System.out.println("show   a:"+a);
    }    
    private void show(String s){
        System.out.println("show   s:"+s);
    }

public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException,
            NoSuchMethodException, SecurityException, InstantiationException,
            IllegalAccessException, IllegalArgumentException,
            InvocationTargetException, NoSuchFieldException {


        Class clazz = Person.class;
        Object obj = clazz.newInstance();
        // Get all public member methods of the Person class
        Method [] methods=clazz.getMethods();

        for(Method m:methods){
            System.out.println(m);
        }

        Method m=clazz.getMethod("show");
        m.invoke(obj);

        Method m1=clazz.getMethod("show",int.class);
        m1.invoke(obj,1);

        Method m2=clazz.getDeclaredMethod("show",String.class);
        m2.setAccessible(true);
        m2.invoke(obj,"smt");
    }
}


//Output results:
Person Class parametric construction
public java.lang.String com.test.demo.Person.toString()
public void com.test.demo.Person.show(int)
public void com.test.demo.Person.show()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
show Empty parameter
show   a:1
show   s:smt

Application of Reflection in Android
Set up the display of icons in menus

 @Override
    public boolean onMenuOpened(int featureId, Menu menu) {
        if (featureId == Window.FEATURE_ACTION_BAR && menu != null) {
            if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
                try {
                    Method m = menu.getClass().getDeclaredMethod(
                            "setOptionalIconsVisible", Boolean.TYPE);
                    m.setAccessible(true);
                    m.invoke(menu, true);
                } catch (Exception e) {
                }
            }
        }
        return super.onMenuOpened(featureId, menu);
    }

Contrast before and after setting


Before setting up

After setting up

Posted by eliezer on Sat, 15 Jun 2019 17:19:17 -0700