天天看点

Java的反射机制一、反射的介绍二、Class类三、反射实例化四、反射动态方法调用 五、反射读写属性

目录

一、反射的介绍

什么是反射?

反射机制的作用 

反射优缺点

二、Class类

概念 

学生类:Student 

获取Class对象的方法 

三、反射实例化

常用方法

实例 

四、反射动态方法调用

常用方法

 实例

 五、反射读写属性

常用方法

实例

一、反射的介绍

什么是反射?

反射就是Java语言中的一种机制,它可以动态的去调用我们的实例化对象,读写属性和调用方法。

反射机制的作用 

通过Java的反射机制我们可以获取我们Class文件加载后的Class对象的所以信息,就比如public修饰的方法属性还有对象,还有我们的private修饰的方法属性和对象,也就是说我们的类变成了透明的,所有的细节都可以获取到。

反射优缺点

优点:

能够运行时动态获取类的实例,提高灵活性;

与动态编译结合;

缺点:

使用反射性能较低,需要解析字节码(.class文件),将内存中的对象进行解析;

相对不安全,破坏了封装性(因为通过反射可以获得私有方法和属性);

解决方案:

1、通过setAccessible(true)关闭JDK的安全检查来提升反射速度;

2、多次创建一个类的实例时,有缓存会快很多;

3、ReflectASM工具类,通过字节码生成的方式加快反射速度 ;

二、Class类

概念 

Java中,每个class都有一个相应的Class对象

也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息

学生类:Student 

后面的实例都是围绕以下学生类进行操作

package com.xyz.mvcdemo.reflect;

public class Student {
	private String sid;

	private String sname;

	public Integer age;
	
	static{
		System.out.println("加载进jvm中!");
	}

	public Student() {
		super();
		System.out.println("调用无参构造方法创建了一个学生对象");
	}

	public Student(String sid) {
		super();
		this.sid = sid;
		System.out.println("调用带一个参数的构造方法创建了一个学生对象");
	}

	public Student(String sid, String sname) {
		super();
		this.sid = sid;
		this.sname = sname;
		System.out.println("调用带二个参数的构造方法创建了一个学生对象");
	}

	@SuppressWarnings("unused")
	private Student(Integer age) {
		System.out.println("调用Student类私有的构造方法创建一个学生对象");
		this.age = age;
	}

	public String getSid() {
		return sid;
	}

	public void setSid(String sid) {
		this.sid = sid;
	}

	public String getSname() {
		return sname;
	}

	public void setSname(String sname) {
		this.sname = sname;
	}

	public void hello() {
		System.out.println("你好!我是" + this.sname);
	}

	public void hello(String name) {
		System.out.println(name + "你好!我是" + this.sname);
	}

	@SuppressWarnings("unused")
	private Integer add(Integer a, Integer b) {
		return new Integer(a.intValue() + b.intValue());
	}

	@Override
	public String toString() {
		return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]";
	}
	
	
}
           

获取Class对象的方法 

Class.forName(完整类名)

类名.class

对象.getClass()

//1.通过Class.forName()获取Class
Class<Student> clazz = (Class<Student>)Class.forName("com.xyz.mvcdemo.reflect.Student");
		
//2.通过 类.class

Class clazz02=Student.class;
		
//3.通过 对象.getClass()
Student stu = new Student();
Class clazz03 = stu.getClass();
           
Java的反射机制一、反射的介绍二、Class类三、反射实例化四、反射动态方法调用 五、反射读写属性

三、反射实例化

常用方法

getConstructor 获得构造器对象
getDeclaredConstructor 获得私有的构造器对象
newInstance 反射实例化
setAccessible(true) 将私有设置可访问

实例 

/**
		 * 公共的构造方法实例对象
		 */
		//通过反射获取对象(无参)
		Constructor<Student> c1 = clazz.getConstructor();
		//通过反射进行实例化对象
		Student stu01 = c1.newInstance();
		//设置属性
		stu01.setSname("小黑");
		System.out.println("stu01="+stu01);
		
		//通过反射获取对象(有参-id)
		Constructor<Student> c2 = clazz.getConstructor(String.class);
		//通过反射进行实例化对象
		Student stu02 = c2.newInstance("111");
		//设置属性
		stu02.setSname("小白");
		System.out.println("stu02="+stu02);
		
		//通过反射获取对象(有参-id,name)
		Constructor<Student> c3 = clazz.getConstructor(String.class,String.class);
		//通过反射进行实例化对象
		Student stu03 = c3.newInstance("121","小蓝");
		System.out.println("stu03="+stu03);
		
		/**
		 * 私有的构造方法实例对象
		 */
		//通过反射获取对象(有参-age)
		Constructor<Student> c4 = clazz.getDeclaredConstructor(Integer.class);
		//设置可以访问该方法
		c4.setAccessible(true);
		//通过反射进行实例化对象
		Student stu04 = c4.newInstance(18);
		System.out.println("stu04="+stu04);
           
Java的反射机制一、反射的介绍二、Class类三、反射实例化四、反射动态方法调用 五、反射读写属性

四、反射动态方法调用

常用方法

getMethod 通过方法名称获取到方法对象
getDeclaredMethod 通过方法名称获取到私有的方法对象
invoke 调用方法

 实例

/**
		 * 调用公共的方法
		 */
		//通过反射获取方法(无参)
		Method method = clazz.getMethod("hello");
		//设置属性
		stu04.setSname("小灰灰");
		//调用方法
		method.invoke(stu04);
		
		//通过反射获取方法(有参)
		Method method02 = clazz.getMethod("hello",String.class);
		//调用方法
		method02.invoke(stu01,"小绿");
		
		/**
		 * 调用私有的方法
		 */
		Method method03 = clazz.getDeclaredMethod("add", Integer.class,Integer.class);
		//设置可以访问该方法
		method03.setAccessible(true);
		//调用方法
		int in = (int)method03.invoke(stu04, 500,20);
		System.out.println(in);
           
Java的反射机制一、反射的介绍二、Class类三、反射实例化四、反射动态方法调用 五、反射读写属性

 五、反射读写属性

常用方法

getField 获得公开的属性
getDeclaredField 既可以获得公开的属性又可以获得私有属性
getDeclaredFields 获得全部

实例

/**
		 * 获取公共的属性
		 */
		Field f = clazz.getField("age");
		//设置属性
		f.set(stu04, 29);
		System.out.println("stu04="+stu04);
		System.out.println("age="+f.get(stu04));
		
		/**
		 * 获取私有的属性
		 */
		Field f01 = clazz.getDeclaredField("sname");
		//设置可以访问该属性
		f01.setAccessible(true);
		//设置属性
		f01.set(stu04, "哈哈");
		System.out.println(stu04);
           
Java的反射机制一、反射的介绍二、Class类三、反射实例化四、反射动态方法调用 五、反射读写属性