Java based learning Summary - reflection

First, what is reflection?

JAVA reflection mechanism is in the operating state, for any class, they are made known to all properties and methods of this class; for any object, are able to call any of its methods and properties; this dynamic and dynamic information obtained function call the object's method is called reflection java language.

Second, you can use reflection to do?

We know that the internal reflection mechanism that allows programs to obtain information about any known class name at runtime, which comprises including constructor (the constructor), fields (attributes), Methods (method) and the like, and can change the contents of fields in the runtime or call methods. Then we can be more flexible to write code, the code can be assembled at run-time, without the need for source code links between components, reducing the coupling of the code; there is the realization of a dynamic proxy etc; but note that improper use of reflection It will result in a high consumption of resources!

Third, pre-knowledge of

(A) loading the class

Want to know how to use reflection, we must first understand the type of load.

When you want to use a class if the class has not yet been loaded into memory, the system by loading, connect, initialize three steps to initialize the class.

  1. Load
    that refers to the class file is read into memory, and whom to create a Class object.
    Any class that is used when the system will build a Class object.
  2. Connection
    to verify that the correct internal structure, and other types of coordinated and
    ready to be responsible for the static member class of allocated memory, and set the default initialization value
    symbol resolution binary data type will replace references in direct reference
  3. The basic initialization of the initialization step

(Ii) class loader

  1. Classloader: .class file responsible for loading the intrinsic in for, and generate the corresponding Class object.
    Although we do not care about class loading mechanism, but understand this mechanism we can run a better understanding of the program.

  2. Composition class loader
    Bootstrap ClassLoader root class loader
    Extension ClassLoader extension class loader
    Sysetm ClassLoader system class loader

  3. Acting class loader
    (1) Bootstrap ClassLoader root class loader, also known as the bootstrap class loader. Responsible for loading the Java core classes
    such as System, String and so on. In rt.jar file under the JDK JRE's lib directory

    (2) Extension ClassLoader extension class loader. Responsible for loading the JRE extensions directory in a jar.
    In the JRE JDK lib directory under the directory ext
    (3) Sysetm ClassLoader system class loader. Responsible for loading class files from the java command, and classpath environment variable specified jar package and class path when JVM startup

Fourth, how to use reflection?

Existing a Person class

public class Person {
	
	private String name;
	int age;
	public String address;

	public Person() {
	}

	private Person(String name) {
		this.name = name;
	}

	Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public Person(String name, int age, String address) {
		this.name = name;
		this.age = age;
		this.address = address;
	}

	public void show() {
		System.out.println("show");
	}

	public void method(String s) {
		System.out.println("method " + s);
	}

	public String getString(String s, int i) {
		return s + "-->" + i;
	}

	private void function() {
		System.out.println("function");
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", address=" + address
				+ "]";
	}
}

So for this class, how to use the reflection of it?

(A) Get Class object corresponding to the class bytecode files in memory

/**
 *有三种方式可以获得Class对象
 */
//1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object
//  类型的对象,而我不知道你具体是什么类,用这种方法
  Person p1 = new Person();
  Class c1 = p1.getClass();
        
//2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
//  这说明任何一个类都有一个隐含的静态成员变量 class
  Class c2 = Person.class;
        
//3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
//   但可能抛出 ClassNotFoundException 异常
  Class c3 = Class.forName("com.ys.reflex.Person");

Note: a class in the JVM there will only be a Class instance, that we get above c1, c2, c3 were == comparison, the result is true

(B) obtaining the constructor provided by the methods of class Class

  1. Obtaining construction method
/**
 *反射之获取无参构造方法,并使用
 */
public class TestConstructor01 {
	public static void main(String[] args) throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
        //获取无参构造函数
		Constructor con = c.getDeclaredConstructor();	
	
		//创建实例
		Object obj = con.newInstance();
	}
}
/**
 *反射之获取带参构造方法,并使用
 */
public class TestConstructor02 {
	public static void main(String[] args) throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
		//获取构造方法
		Constructor con = c.getDeclaredConstructor(String.class, int.class, String.class);
		
		//创建实例
		Object obj = con.newInstance("张三", 27, "北京");
	}
}
/**
 *反射之获取private修饰的构造方法,并使用
 */
public class TestConstructor03 {
	public static void main(String[] args) throws Exception{
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//获取构造方法
		Constructor con = c.getDeclaredConstructor(String.class);
		
		//设置访问权限
		con.setAccessible(true);	//值为true则指示反射的对象在使用时应该取消Java语言访问检查。
		
		//创建实例
		Object obj = con.newInstance("林青霞");
	}
}

(C) the method provided by the operating member variable classes Class

  1. To the member variable assignment
public class TestField01 {
	public static void main(String[] args) throws Exception{
		test();
	}

	public static void test() throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//获取Constructor
		Constructor con = c.getDeclaredConstructor();
		
		//创建实例
		Object obj = con.newInstance();
		System.out.println(obj);
		
		//获取Field
		Field addressField = c.getDeclaredField("address");
		//赋值Field
		addressField.setAccessible(true);
		addressField.set(obj, "北京");
		System.out.println(obj);
		
		Field nameField = c.getDeclaredField("name");
		nameField.setAccessible(true);  	
		nameField.set(obj, "张三");
		System.out.println(obj);
		
		Field ageField = c.getDeclaredField("age");
		ageField.setAccessible(true);
		ageField.set(obj, 27);
		System.out.println(obj);
	}
}

Test results are as follows:

  1. Acquiring member variables
public class TestField02 {
	public static void main(String[] args) throws Exception{
		test();
	}

	public static void test() throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//获取Constructor
		Constructor con = c.getDeclaredConstructor();
		
		//创建实例
		Object obj = con.newInstance();
		System.out.println(obj);
        
		//获取Field
		Field addressField = c.getDeclaredField("address");
		//赋值Field
		addressField.setAccessible(true);
		addressField.set(obj, "北京");
		System.out.println(obj);
		System.out.println(addressField.get(obj));
	}
}	

Test results are as follows:

(Iv) the method by method calls the members of the Class class provides

/**
 * 反射之获取无参无返回值成员方法,并调用
 */
public class TestMethod01 {
	public static void main(String[] args) throws Exception {
		test0();
	}
	
	//获取单个方法对象
    /**
    * 1、public 方法 getMethod(String name, Class<?>... parameterTypes):获取所有方法,包括父类的
    * 参数 :	name:方法的名称  parameterTypes:该方法的参数列表 
    * 2、public 方法 getDeclaredMethod(String name, Class<?>... parameterTypes):获取所有子类定义的方法
    * 参数 :	name:方法的名称  parameterTypes:该方法的参数列表 
    */	
	public static void test() throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//获取构造方法
		Constructor con = c.getDeclaredConstructor();
		
		//创建实例
		Object obj = con.newInstance();
		
		//获取需要的方法对象
	
		Method m = c.getDeclaredMethod("show");
		
		//调用方法
		/**
		 * public Object invoke(Object obj, Object... args)
		 * obj - 被调用的对象  args - 用于方法调用的参数
		 */
		m.invoke(obj);
	}
}

Test results are as follows:

/**
 * 反射之获取有参有返回值成员方法,并调用
 */
public class TestMethod02 {
	public static void main(String[] args) throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//获取构造方法
		Constructor con = c.getDeclaredConstructor();
		
		//创建实例
		Object obj = con.newInstance();
		
		//获取需要的方法对象
		//public void method(String s)
		Method m = c.getDeclaredMethod("method", String.class);
		m.invoke(obj, "java");
		
		//public String getString(String s, int i) 
		Method m1 = c.getDeclaredMethod("getString", String.class, int.class);
		Object rst = m1.invoke(obj, "hello", 200);
		System.out.println(rst);
	}
}

Test results are as follows:

/**
 * 反射之获取privste成员方法,并调用
 */
public class TestMethod02 {
	public static void main(String[] args) throws Exception {
		//获取Class对象
		Class c = Class.forName("study01.Person");
		
		//获取构造方法
		Constructor con = c.getDeclaredConstructor();
		
		//创建实例
		Object obj = con.newInstance();
		
		//获取需要的方法对象
		//private void function()
		Method m2 = c.getDeclaredMethod("function");
		m2.setAccessible(true);
		m2.invoke(obj);
	}
}

Test results are as follows:

V. Summary

Flexible use of reflection allows us to code more flexible, but everything has two sides performance, reflecting consumption of the system will increase the complexity, etc., is really fair use!

Guess you like

Origin www.cnblogs.com/Java-biao/p/12589636.html