Java修炼——反射机制

反射机制常见的作用:

1) 动态的加载类、动态的获取类的信息(属性,方法,构造器)

2) 动态构造对象

3) 动态调用类和对象的任意方法、构造器

4) 动态调用和处理属性

5) 获取泛型信息

       6) 处理注解

先创建一个User类:

package com.bjsxt.entity;

public class User {
	private int uid;
	public String name;
	private String password;
	public int getUid() {
		return uid;
	}
	public void setUid(int uid) {
		this.uid = uid;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	//构造方法
	public User(int uid, String name, String password) {
		super();
		this.uid = uid;
		this.name = name;
		this.password = password;
	}
	public User() {
		super();
	}
	
}

获取Class对象的三种方法:

1) 通过字节码文件

2) 对象的 getClass()方法

3) Class 类的静态方法 forName(….)

package com.bjsxt.reflect;

import com.bjsxt.entity.User;

public class TestGetClass {
	public static void main(String[] args) throws ClassNotFoundException {
		System.out.println("获取intClass对象:"+int.class);
		System.out.println("获取voidClass对象:"+void.class);
		
		int [] arraya=new int[20];
		int [] arrayb=new int[30];
		double [] arrayc=new double[30];
		/**维数相同和类型相同共享同一个Class对象*/
//		System.out.println(arrayc.getClass()==arrayb.getClass());//报错
		System.out.println("arraya和arrayb是否是同一个Class对象:"+(arraya.getClass()==arrayb.getClass()));
		 
		//创建User类的对象
		/**同一个类N多个对象,共享同一个Class对象*/
		User user1=new User(1001, "李四", "123");
		User user2=new User(1002, "李思", "125");
		System.out.println("user1和user2是否是同一个Class对象:"+(user1.getClass()==user2.getClass()));
		
		//获取Class的三种方式
		
		//1.通过对象的getClass()获取
		Class c1=user1.getClass();
		//2.通过字节码文件获取
		Class c2=User.class;
		//3.通过Class类的静态方法获取
		Class c3=Class.forName("com.bjsxt.entity.User");
		
		System.out.println((c1==c2)+"\t"+(c2==c3));
	}
}

 

反射机制动态操作方法_属性_构造器:

       获取类名的方法:

1  String getName()  获得包名+类名

2  String getSimpleName() 获得类的名字

获取属性对象的方法

1  Field getField(String fieldName)  得到公共的属性对象

2  Field getDeclareField(String fieldName)  得到指定名称的属性对象

3  Field []c.getDeclaredFields()  得到所有的属性对象

获取方法以及构造方法:

1  Method[] getDeclaredMethods()  得到公共的方法对象

2  Method[] c.getMethods()  得到父类及本类中的公共的方法对象

3  Method  getDeclaredMethod(String methodName, Class …type)得到指定名称的本类中公共的方法

4  Method  getMethod(String  methodName,Class type)得到本类或父类中的公共的方法对象

1  Constructor[] getDeclaredConstructors()  得到公共的构造方法的对象

2  Constructor [] getConstructors()  得到公共的构造方法对象

3  ConstructorgetDeclaredConstructor(Class...type)得到指定参数的公共的构造方法对象

package com.bjsxt.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class TestDongTai {
	final public static String path="com.bjsxt.entity.User";//完全是为了后面写代码的方便
	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException {
		//1.获取类的名称
		System.out.println("\n********************获取类的名称*****************");
			Class c=Class.forName(path);
			System.out.println("获取类的全名(包名和类名):"+c.getName());
			System.out.println("获取类的名字:"+c.getSimpleName());
			
			//获取父类的Class对象
			Class csuper=c.getSuperclass();
			System.out.println("\n获取父类的全名(包名和类名):"+csuper.getName());
			System.out.println("获取父类的名字:"+csuper.getSimpleName());
			
			
		//2.获取类的属性信息
			System.out.println("\n********************获取类的属性信息*****************");
//			Field fid = c.getField("uid");
			Field fname = c.getField("name");
//			System.out.println("获取类的公共属性:"+fid);//错误,因为id是私有的。
			System.out.println("获取类的公共属性:"+fname);//public java.lang.String com.bjsxt.entity.User.name
			System.out.println("\n");
			Field[] fields = c.getFields();//获取类的所有公共属性
			for (Field field : fields) {
				System.out.println("获取类的所有公共属性:"+field);
			}
			Field[] fs = c.getDeclaredFields();//获取类的所有属性
			for (Field fis : fs) {
//				System.out.println("获取类的所有属性:"+fis);//重写tostring方法 
				/**访问级别:public 1; private 2; protected 4;*/
				System.out.println("获取级别:"+fis.getModifiers()+"\t获取类型:"+fis.getType()+"\t获取属性名字:"+fis.getName());
		
			}
			
		//3.获取类的方法信息
			System.out.println("\n********************获取类的方法信息*****************");
			Method[] ms = c.getDeclaredMethods();//获得本类中的所有方法对象
			System.out.println("本类有多少个方法:"+ms.length);
			for (Method method : ms) {
//				System.out.println(method);
				System.out.println("访问权限:"+method.getModifiers()+"\t方法返回值类型:"+method.getReturnType()+"\t方法名称:"+method.getName());
				Class[] pt = method.getParameterTypes();
				for (Class c1 : pt) {
					System.out.println("方法参数:"+c1.getTypeName()+"\t");
				}
				System.out.println("\n***********************");
			}
			
		//4.类的获取构造方法
			System.out.println("\n******************类的获取构造方法************************");
			Constructor[] cs = c.getConstructors();
			System.out.println("获取所有的构造方法:");
			for (Constructor constructor : cs) {
				System.out.println(constructor);
			}
			System.out.println("\n获取无参构造方法:");
			Constructor cnull = c.getConstructor(null);
			System.out.println(cnull);
			System.out.println("\n获取有参构造方法:");
			Constructor con = c.getConstructor(int.class,String.class,String.class);
			System.out.println(con);
	}
}

运行结果 :

 

提高反射效率:

通过 setAccessible 提高性能

a) setAccessible 启用和禁用访问安全检查的开关,值为true 则指示反射的对 象在使用时应该取消 Java 语言访问检查,值为 false 则指示反射的对象不 实施Java 语言访问检查,并不是为 true 就能访问为 false 就不能访问

b) 禁止安全检查,可以提高反射的运行速度

posted @ 2019-12-11 08:56  sakura-yxf  阅读(85)  评论(0)    收藏  举报