反射

什么是反射?

通过字节码对象创建对象,获取构造器,方法,字段

什么是字节码对象?

JVM将java类编译成一份份字节码文件(.class),因此从众多的字节码文件中抽取出他们的共性形成一个Class类,该类具有所有字节码文件的特点(字段,方法,构造器),因此该类的对象被称为字节码对象
可以通过字节码对象去创建对象,操作该类中的方法/字段/构造器/这种过程成为反射
反射主要掌握字节码的获取,一般使用forName(“全限定名”)的方式
其余所有的操作都是根据字节码对象来操作的
获取构造器/方法/字段/创建对象
1.反射的使用场景
有些时候我们无法看到源码,不知道一个对象的具体类型,此时无法强转
这个时候就需要用到反射,去获取该对象的信息
2.反射的基本使用
(1).获取字节码对象
三种方式:
类名.class
对象名.getClass()
forName(“全限定名”)
(2).获取构造器
通过字节码对象获取/所有构造器/指定构造器/公共的/全部包括私有(getDeclared…)
(3).获取方法
通过字节码对象获取/所有方法/指定方法/公共的/全部包括私有(getDeclared…)
(4).获取字段
通过字节码对象获取/所有字段/指定字段/公共的/全部包括私有(getDeclared…)
注意:
在使用反射时注意参数的传递,比如形参传递的是类型(如:String.class,因为是通过字节码对象获取的构造器/方法,所以这里也需使用字节码对象的类型);
在使用Declared的构造器/方法/字段时,要设置访问权限Accessible;
因为创建对象的时候使用公共无参构造器的频率比较高,所以使用 字节码对象.newInstance可以直接创建对象;

代码片

public void testInstance1() throws Exception {
		//获取字节码对象的三种方式
		//方式一
		Class clz1 = Class.forName("com.reflect.User");
		//方式二
		//User u=new User();
		//Class clz2= u.getClass();
		//方式三
		Class clz3=User.class;
		//通常使用forName();
		//获取所有公共的构造器
		Constructor[] constructors = clz1.getConstructors();
		for (Constructor con : constructors) {
			System.out.println(con);
		}
		System.out.println("--------------------------------------");
		//获取所有的构造方法包括私有的
		Constructor[] con2 = clz1.getDeclaredConstructors();
		for (Constructor cons : con2) {
			System.out.println(cons);
		}
		// 获取公共无参构造器
		Constructor constructor = clz1.getConstructor();
		// 使用无参构造器创建对象
		Object obj = constructor.newInstance();
		// 获取方法一
		Method m = clz1.getMethod("method1");
		m.invoke(obj, null);

	}
	@Test
	public void testinstance2() throws Exception {
		Class clz1 = Class.forName("com.reflect.User");
		//获取三个参数的构造器
		Constructor con=clz1.getConstructor(String.class,int.class,String.class);
		//使用三参数的构造器创建对象
		Object obj = con.newInstance("王昭君",24,"女");
		System.out.println(obj);
		System.out.println("------------------------------------");
		//获取所有的公共的方法
		Method[] methods = clz1.getMethods();
		for (Method method : methods) {
			System.out.println(method);
		}
		System.out.println("------------------------------------");
		//获取所有的方法包括私有的
		Method[] declar = clz1.getDeclaredMethods();
		for (Method method : declar) {
			System.out.println(method);
		}
		System.out.println("------------------------------------");
		//获取含参数的方法,形参为参数类型
		Method method = clz1.getMethod("method2", String.class);
		//调用方法 传入实参
		method.invoke(obj, "貂蝉");

	}
	@Test
	public void testinstance3() throws Exception {
		Class clz1 = Class.forName("com.reflect.User");
		//获取私有的构造器
		Constructor con=clz1.getDeclaredConstructor(String.class,int.class);
		//设置访问权限为true
		con.setAccessible(true);
		Object obj=con.newInstance("吕布",2);
		System.out.println(obj);
		//获取私有的方法
		Method m=clz1.getDeclaredMethod("method4", String.class);
		//设置访问权限
		m.setAccessible(true);
		//调用
		m.invoke(obj, "张飞");
	}
	@Test
	public void testinstance4() throws Exception {
		Class clz1 = Class.forName("com.reflect.User");
		//使用公共无参构造器创建对象,使用太频繁,精简操作
		Object instance = clz1.newInstance();
		System.out.println(instance);
	}
	@Test
	public void testFileds() throws Exception {
		Class clz1 = Class.forName("com.reflect.User");
		//获取所有字段
		Field[] fields = clz1.getDeclaredFields();
		for (Field field : fields) {
			System.out.println(field);
		}
		Object obj = clz1.newInstance();
		//获取指定字段
		Field fName = clz1.getDeclaredField("name");
		fName.setAccessible(true);
		//给指定字段赋值
		fName.set(obj, "鲁班");
		Field fAge = clz1.getDeclaredField("age");
		fAge.setAccessible(true);
		fAge.set(obj, 2);
		Field fGender = clz1.getField("gender");
		fGender.set(obj, "女");
		System.out.println(obj);
	}

学习阶段,如有问题,欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值