Java -- 类加载器&反射&代理

类加载&类加载器

类的加载描述:

反射&reflect

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。

  • Class类的获取

    /*for example*/
    public class TestClass {
    	public static void main(String[] args) throws ClassNotFoundException {
    		/* 类的三种获取方式 */
    		/* the first... */
    		Person p = new Person();
    		Class pClass = p.getClass();
    		System.out.println(pClass);
    
    		/* the second... */
    		Class sClass = Person.class;
    		System.out.println(sClass);
    
    		/* the third... */
    		Class tClass = Class.forName("ReflectionTools.Person");
    		System.out.println(tClass);
    	}
    }
    
  • Class类构造方法的获取

    /*for example*/
    /* 仅仅显示由public修饰的构造方法 */
    	Constructor[] con = tClass.getConstructors();
    	for (Object obj : con)
    		System.out.println(obj);
    	Constructor[] conAll = tClass.getDeclaredConstructors();
    	System.out.println("------- this is a dividing line --------");
    
    /* 所有的构造方法都显示出来. */
    	for (Object obj : conAll)
    		System.out.println(obj);
    	System.out.println("------- this is a dividing line --------");
    
  • Class类字段的获取

    /*for example*/
    与构造方法完全一样,用Field替换对应的部分即可。
    
  • Class类成员方法的获取

    /*for example*/
    不同之处在于getMethods方法获取的是获取的所有方法,包括父类的的public修饰的。
    getDeclaredMethods是自己的所有修饰符修饰的成员方法。
    
  • 使用带Declared的函数获取的函数是完整的,但是若需要使用指定的成员变量与成员方法,则可以利用反射。使用对应的带参数的函数+函数名称即可调用,若是非公有的,可以使用setAccessiable強制調用。

    /*for example   非局部的使用*/
    
    /*PJO定义一个简单的类*/
    package ReflectionTools;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    class Person {
    	private String name;
    	private int age;
    	private String address;
    
    	/* 私有的带参构造方法。 */
    	private Person(String name, int age) {
    		this.name = name;
    		this.age = age;
    	}
    
    	public Person(String name) {
    		this.name = name;
    	}
    
    	public Person(String name, int age, String address) {
    		super();
    		this.name = name;
    		this.age = age;
    		this.address = address;
    	}
    
    	/* 无参构造方法. */
    	Person() {
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	private void setAge(int age) {
    		this.age = age;
    	}
    
    	public String getAddress() {
    		return address;
    	}
    
    	public void setAddress(String address) {
    		this.address = address;
    	}
    
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + ", address=" + address
    				+ "]";
    	}
    }
    
    
    /*测试主函数*/
    public class TestClass {
    
    	public static void main(String[] args) throws ClassNotFoundException,
    			NoSuchMethodException, SecurityException, InstantiationException,
    			IllegalAccessException, IllegalArgumentException,
    			InvocationTargetException, NoSuchFieldException {
    		/* 类的三种获取方式 */
    		/* the first... */
    		Person p = new Person();
    		Class pClass = p.getClass();
    		System.out.println(pClass);
    
    		/* the second... */
    		Class sClass = Person.class;
    		System.out.println(sClass);
    
    		/* the third... */
    		Class tClass = Class.forName("ReflectionTools.Person");
    		System.out.println(tClass);
    
    		System.out.println("-------this is a dividing line--------");
    
    		/* 仅仅显示由public修饰的构造方法 */
    		Constructor[] con = tClass.getConstructors();
    		for (Object obj : con)
    			System.out.println(obj);
    		Constructor[] conAll = tClass.getDeclaredConstructors();
    		System.out.println("------- this is a dividing line --------");
    		/* 所有的构造方法都显示出来. */
    		for (Object obj : conAll)
    			System.out.println(obj);
    		System.out.println("------- this is a dividing line --------");
    
    		/* 无参数构造方法的使用。 */
    		Constructor conSpecific = tClass.getDeclaredConstructor();
    		Object obj = conSpecific.newInstance();
    		
    		/*调用private修饰的变量*/
    		Field fieldSpecific = tClass.getDeclaredField("name");
    		fieldSpecific.setAccessible(true);
    		fieldSpecific.set(obj, "Tom");
    
    		/* 调用非public修饰的成员方法 */
    		Method methodSpecific = tClass.getDeclaredMethod("setAge", int.class);
    		methodSpecific.setAccessible(true);
    		methodSpecific.invoke(obj, 5);
    		System.out.println(obj);
    	}
    }
    
    /*控制台输出结果为:*/
    	class ReflectionTools.Person
    	class ReflectionTools.Person
    	class ReflectionTools.Person
    	-------this is a dividing line--------
    	public ReflectionTools.Person(java.lang.String,int,java.lang.String)
    	public ReflectionTools.Person(java.lang.String)
    	------- this is a dividing line --------
    	private ReflectionTools.Person(java.lang.String,int)
    	ReflectionTools.Person()
    	public ReflectionTools.Person(java.lang.String,int,java.lang.String)
    	public ReflectionTools.Person(java.lang.String)
    	------- this is a dividing line --------
    	Person [name=Tom, age=5, address=null]
    
  • 反射的应用

    • 构造一个动态的对象调用动态的方法:

      /*for example*/
      /**config.ini是配置class类和对应方法的。/
      
      package ReflectionTools;
      
      import java.io.FileReader;
      import java.io.IOException;
      import java.lang.reflect.Constructor;
      import java.lang.reflect.InvocationTargetException;
      import java.lang.reflect.Method;
      import java.util.Properties;
      
      /*config.ini*/
      	/*content:
      	 className = ReflectionTools.personTest
      	 classValue = hobby
      	 */
      
      class animal {
      	private String name;
      
      	public animal() {
      	}
      
      	public void show() {
      		System.out.println(this.name + "this is animailShow!");
      	}
      }
      
      class personTest {
      	private String name;
      	private int age;
      	private String address;
      
      	public personTest() {
      	}
      
      	public void hobby() {
      		System.out.println(this.name + "this is a personHobby!" + this.age
      				+ this.address);
      	}
      }
      
      public class ReflectionApp {
      	public static void main(String[] args) throws IOException,
      			ClassNotFoundException, InstantiationException,
      			IllegalAccessException, IllegalArgumentException,
      			InvocationTargetException, NoSuchMethodException, SecurityException {
      		/* 使用throws不必初始化,直接异常弹出,这样的目的是为了防止空指针异常。 */
      
      		FileReader fileReader = new FileReader("config.ini");
      		Properties keyValue = new Properties();
      		keyValue.load(fileReader);
      		fileReader.close();
      
      		String getNameID = keyValue.getProperty("className");
      		String getValueID = keyValue.getProperty("classValue");
      		Class classFiles = Class.forName(getNameID);
      
      		Constructor con = classFiles.getConstructor();
      		Object obj = con.newInstance();
      		Method meTest = classFiles.getDeclaredMethod(getValueID);
      		meTest.invoke(obj);
      
      	}
      }		
      
    • 反射修改泛型

      import java.lang.reflect.InvocationTargetException;
      import java.lang.reflect.Method;
      import java.util.ArrayList;
      
      /*
       * 我给你ArrayList<Integer>的一个对象,要求在这个集合中添加一个字符串数据。
       */
      public class ArrayLis{
      	public static void main(String[] args) throws NoSuchMethodException,
      			SecurityException, IllegalAccessException,
      			IllegalArgumentException, InvocationTargetException {
      
      		/*创建集合对象*/
      		ArrayList<Integer> array = new ArrayList<Integer>();
      
      		Class classfile = array.getClass(); /*集合ArrayList的class文件对象*/
      		Method me = classfile.getMethod("add", Object.class);
      
      		me.invoke(array, "hello"); /*调用array的add方法,传入的值是hello.*/
      		me.invoke(array, "world");
      		System.out.println(array);
      	}
      		}
      
  • Proxy代理对象

    • 描述:代理一个对象的操作,结合InvocationHandler接口,只能实现对接口的代理。若要对类进行代理需要使用cglib。
    • tip:该类代理不会再框架中使用,故而略…

猜你喜欢

转载自blog.csdn.net/CS_GaoMing/article/details/84142666
今日推荐