反射

什么是反射

反射java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法

反射获取类对象(三种方式)

我们先来创建一个Student类

package com.xieminglu.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 + "]";
	}
}

1.Class.forName(“类的全路径名”); 常用与jdbc、自定义mvc框架

Class<?> class1 = Class.forName("com.xieminglu.reflect.Student");
System.out.println(class1);

输出的结果为:
在这里插入图片描述

2.类名.class 做通用查询

Class<?> class1 = Student.class;	
System.out.println(class1);

输出的结果为:
在这里插入图片描述

3.类(Class类类的类对象)实例.getClass() 做通用的增删改

Student stu=new Student();
Class<?> class1 = stu.getClass();
System.out.println(class1);

输出的结果为:
在这里插入图片描述

一切反射相关的代码都从获得类(java.lang.Class)对象开始

3.1 Class.forName(完整类名)
3.2 类名.class
3.3 对象.getClass()

反射实例化

1.能够实例化未知的类
2.能够通过私有构造器创建实例

Student stu=(Student)cla.newInstance();

输出的结果为:
在这里插入图片描述

//		拿到构造器类
		Constructor<Student> con = cla.getConstructor(String.class);
//		通过构造器实例化对象
		Student student = (Student)con.newInstance("s001");

输出的结果为:
在这里插入图片描述

Constructor<Student> con = cla.getConstructor(String.class,String.class);
Student student = (Student)con.newInstance("s001","zs");

输出的结果为:
在这里插入图片描述

Constructor<Student> con = cla.getConstructor(Integer.class);
Student student = (Student)con.newInstance(1);

输出的结果为:
在这里插入图片描述

这个报错的原因是因为getConstructor只能找到public修饰的构造器,getDeclaredConstructor可以找到任何修饰符的构造器

Constructor<Student> con = cla.getDeclaredConstructor(Integer.class);
Student student = (Student)con.newInstance(1);

输出的结果为:
在这里插入图片描述
这个报错的原因public是私有的不让访问,我们得设置让它访问

Constructor<Student> con = cla.getDeclaredConstructor(Integer.class);
con.setAccessible(true);
Student student = (Student)con.newInstance(1);

输出的结果为:
在这里插入图片描述
反射调用方法

Student stu=new Student();
stu.hello();

输出的结果为:
在这里插入图片描述

Student stu=new Student();
Class cla=stu.getClass();
Method m=cla.getDeclaredMethod("hello");
m.invoke(stu);

输出的结果为:
在这里插入图片描述

Student stu=new Student();
Class cla=stu.getClass();
Method m=cla.getDeclaredMethod("hello",String.class);
m.invoke(stu,"zs");

输出的结果为:
在这里插入图片描述

Student stu=new Student();
Class cla=stu.getClass();
Method m=cla.getDeclaredMethod("add",Integer.class,Integer.class);
m.setAccessible(true);
//invoke如果反射动态调用的方法是被void所修饰,那么返回的是null
//如果反射动态调用的方法不被void所修饰,那么返回的就是被调用的方法的返回值
Object invoke = m.invoke(stu,20,5);
System.out.println(invoke);

输出的结果为:
在这里插入图片描述

反射属性赋值取值

package com.xieminglu.reflect;

import java.lang.reflect.Field;

/*
 * 反射属性赋值取值
 * *
 */
public class Demo4 {

	public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		Student stu=new Student();
		stu.setSid("s001");
		stu.age=22;
		System.out.println(stu);
//		反射赋值
		Class cla=stu.getClass();
		Field f = cla.getDeclaredField("sid");
		Field f1 = cla.getDeclaredField("age");
		f.setAccessible(true);
		f.set(stu, "s002");
		f1.set(stu, 28);
		System.out.println(stu);
//		读
		System.out.println(f.get(stu));
		System.out.println(f1.get(stu));
//		使用反射读取
		Field[] fields = cla.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			System.out.println(field.getName() + " : " + field.get(stu));
		}
	}
}

输出的结果为:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值