反射

①什么是反射?

概念:
反射java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法
作用:
能够让代码更具灵活性,能够将未知的对象进行实例化

②反射的调取方法

核心点:一切反射相关的代码都从获得类对象开始

1.获取类对象的三种方式

方法介绍
Class.forName(“完整类名”)通过class.forName获取类对象
Xxx.class类名点class返回一个Class类对象
对象点getClass()先实例化对象在调取.getClass返回去类对象

这里以实例给大家展示

package com.tanle.reflect;
/**
 * 
 * @author tanle
 *	获取类对象的三种方式
 *		Class.forName("")
 *		Xxx.class
 *		对象.getClass
 *
 */
public class Demo1 {
	public static void main(String[] args) throws Exception {
		//调取
		//①
		Class<?> forName = Class.forName("com.tanle.reflect.Student");
		System.out.println(forName);
		//②
		Class forName2=Student.class;
		System.out.println(forName2);
		//③
		Student stu=new Student();
		Class forName3 = stu.getClass();
		System.out.println(forName3);
	
	}
}

代码执行结果
在这里插入图片描述

2.反射实例化对象

都需要先获取类对象(以代码的方式给大家看,里面书写了一些可能会报的错误)

方法介绍
newInstance();无参共有的实例化
getConstructor(类型.class)有一个参数的共有构造器实例化
getConstructor(类型.class,类型.class)有两个参数的共有构造器实例化
getDeclaredConstructor(类型.class)私有的构造器实例化
package com.tanle.reflect;

import java.lang.reflect.Constructor;

/**
 * 
 * @author tanle
 *
 *	反射实例化对象
 *		1.无参共有的实例化
 *		2.有一个参数的共有构造器实例化
 *		3.有两个参数的共有构造器实例化
 *		4.私有的构造器实例化
 */		
public class Demo2 {
	public static void main(String[] args) throws Exception{
		//oop实例化对象
		Student stu=new Student();
		Class<? extends Student> cla = stu.getClass();
		//反射实例化对象
		//1.无参共有的实例化
		System.out.println("1.无参共有的实例化");
		Student stu2 = (Student) cla.newInstance();
		System.out.println(stu2);

		//可能会报的错误
		//java.lang.NoSuchMethodException:student类中没有Interger为参数的构造方法
		//getConstructor是获取到public 修饰的构造方法
		//getDeclaredConstructor能够获取到任意修饰符的构造器
		//Exception in thread "main" java.lang.IllegalAccessException:非法访问,应为这个构造器是private修饰
		
		//2.有一个参数的共有构造器实例化
		System.out.println("2.有一个参数的共有构造器实例化:");
		Constructor<? extends Student> c= cla.getConstructor(String.class);
		Student stu3 = c.newInstance("s001");
		System.out.println(stu3);
		//3.有两个参数的共有构造器实例化
		System.out.println("3.有两个参数的共有构造器实例化:");
		Constructor<? extends Student> c1= cla.getConstructor(String.class,String.class);
		Student stu4 = c1.newInstance("s001","张三");
		System.out.println(stu4);
		
		//4.私有的构造器实例化
		System.out.println("4.私有的构造器实例化:");
		Constructor<? extends Student> c2= cla.getDeclaredConstructor(Integer.class);
		c2.setAccessible(true);
		Student stu5 = c2.newInstance(2);
		System.out.println(stu5);
		
		
		
	}
}

代码执行结果
在这里插入图片描述

3.反射调用方法

都是以类对象为前提的
动态被调用的方法,如果该方法是void类型的返回值,那么invoke,此时结果为null

方法介绍
getMethod(“方法名”);类对象 点getMethod返回一个Method
getMethod(“方法名”,数据类型.class)有一个参数的方法调用
getDeclaredMethod(“方法名”, 数据类型.class)私有的方法调用
package com.tanle.reflect;

import java.lang.reflect.Method;

/**
 * 
 * @author tanle
 *
 * 调用方法
 *	 	1.无参共有的方法调用
 *		2.有一个参数的方法调用
 *		3.私有的方法调用
 * 
 */
public class Demo3 {
	public static void main(String[] args) throws Exception{
		Student stu=new Student();
		Class<? extends Student> cla=stu.getClass();
		Method m = cla.getMethod("hello");
		Object invoke = m.invoke(stu);
		//动态被调用的方法,如果该方法是void类型的返回值,那么invoke,此时结果为null
		System.out.println(invoke);
		//2.有一个参数的方法调用
		Method m2 = cla.getMethod("hello",String.class);
		Object invoke2 = m2.invoke(stu, "狗蛋");
		System.out.println(invoke2);
		
		//3.私有的方法调用
		Method m3 = cla.getDeclaredMethod("add", Integer.class,Integer.class);
		m3.setAccessible(true);
		Object invoke3 = m3.invoke(stu, 20,5);
		//动态被调用的方法,如果该方法是非void类型的返回值,那么invoke后就是该方法被调用的结果
		System.out.println(invoke3);
	}
}

代码执行结果

在这里插入图片描述

4.反射读取属性

1.共有的属性 2.私有的属性
一般都使用私有的方法进行调用

package com.tanle.reflect;

import java.lang.reflect.Field;

/**
 * 
 * @author tanle
 *
 * 反射读写属性
 * 		1.共有的属性
 * 		2.私有的属性
 * 		
 */
public class Demo4 {
	//获取success这个变量被那些修饰符所修饰
	//private 代表1
	//public 代表2
	private static final String success="登录成功";
	
	public static void main(String[] args) throws Exception{
		Student stu=new Student("s001","狗蛋");
		stu.age=22;
		Class<? extends Student> cla = stu.getClass();
		//2.私有的属性
		Field f = cla.getDeclaredField("sname");
		f.setAccessible(true);
		System.out.println(f.get(stu));
		
		//反射读写属性的常用方法(一次性获取该类的所有属性值)
		Field[] fs = cla.getDeclaredFields();
		for (Field fi : fs) {
			fi.setAccessible(true);
			System.out.println(fi.get(stu));
		}
		
		//设置
		//通过反射改变sname对应的值
		f.set(stu, "铁蛋");
		System.out.println(stu.getSname());
		
		
	
	}
}

代码运行结果
在这里插入图片描述

③Student类代码展示

package com.tanle.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());
	}
}

④总结

反射对其他一些框架来说是基础代码块,所有一定要整明白o
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值