Java 反射机制

 

目录

1.反射的概念

2.反射实现的功能

3.反射的要点

4.获取类对象|源头

5.获取构造器

6.获取方法

7.获取属性|字段

8.获取父类的|父接口的的类对象

9.创建类型对象根据类对象

10.修饰符


1.反射的概念

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为的Java语言的反射机制。

2.反射实现的功能

①在运行时判断任意一个对象所属的类;
②在运行时构造任意一个类的对象;
③在运行时判断任意一个类所具有的成员变量和方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理。

3.反射的要点

  • 反射是发生在程序的运行期间
  • 在类加载的时候,在内存中就会存在一个这个类的类对象,对象中存在这个类的所有信息(方法,属性,构造器...)
  • 在创建的对象的时候,得到的是这个类对象的一个​​镜像|复制体
  • 如果拿到了类型类类的实例,就可以进行一切操作

4.获取类对象|源头

  1. 类名的的.class
  2. 对象.getClass()
  3. 的Class.forName(“包名+类名”); ----最推荐
public static void main(String[] args) throws ClassNotFoundException {
		//test("Apple");
		
		//1.类名.class
		Class ref=RefletDemo07.class;
		System.out.println(ref.getName());
		
		RefletDemo07 ref2=new RefletDemo07();
		//2.2.对象.getClass()
		Class<?> r=ref2.getClass();
		System.out.println(r);
		//3.Class.forName("包名+类名");
		Class<?> r2=Class.forName("reflect.RefletDemo07");
		System.out.println(r2);
		
	}
	
	static void test(String str) throws ClassNotFoundException{
		if("Apple".equals(str)){
//			new Apple();
			Class.forName("com.relect.Apple");
		}else{
//			new Banana(); //香蕉
			Class.forName("com.relect.Banana");
		}
	}

5.获取构造器

  1. Contrustor getContrustor(Class ...);获取公共的指定的构造器。
  2. Contrustor [] getContrustors();获取公共的所有的构造器。
  3. 构造函数<T> getDeclaredConstructor(Class <?> ... parameterTypes)获取指定的某个构造器。
  4. Constructor [] getDeclaredConstructors()获取所有的构造器(包括私有)。
public class ReflectDemo08{
	private String name;
	
	public static void main(String[] args) throws NoSuchMethodException, SecurityException {
		//1.获取	Class对象
		Class ref=ReflectDemo08.class;
		//获取指定的公共股构造
		/*Constructor con=ref.getConstructor(String.class);
		System.out.println(con);*/
		//获取所有公共的构造器
		Constructor[] cons=ref.getConstructors();
		for(Constructor c:cons){
			System.out.println(c);
		}
		//获取指定的私有构造器
		Constructor con2=ref.getDeclaredConstructor();
		System.out.println(con2);
		//获取所有的私有构造器
		Constructor[] con2s=ref.getDeclaredConstructors();
		for(Constructor c:con2s){
			System.out.println(c);
		}
	}
	
	private ReflectDemo08() {
		// TODO Auto-generated constructor stub
	}	
	
	private ReflectDemo08(String name) {
		super();
		this.name = name;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
}

6.获取方法

  1. 方法getMethod(方法名,Class <?> ... parameterTypes); 获取公共的指定的方法
  2. 方法[] getMethods(); 获取公共的所有的方法
  3. 方法<T> getDeclaredMethod(方法名,Class <?> ... parameterTypes)获取指定的某个方法
  4. Method [] getDeclaredMethods()获取所有的方法(包括私有)
  • 方法对象.invoke(类型的对象,参数);

注意:

如果在本类中正常使用。

如果外类中使用私有的,需开放权限:setAccessible(false) - > true(放开)默认false(关闭)

public static void getMethods() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{
		Class cls=Class.forName("reflect.ReflectDemo10"); 
		ReflectDemo10 ref=(ReflectDemo10) cls.newInstance();
		
		Method[] methods= cls.getDeclaredMethods();
		for(Method m:methods){
			System.out.println(m);  //获取方法名名字   是所有修饰符代表数字的和
		}
//		methods[2].invoke(ref, "周杰伦");
//		methods[3].invoke(ref);
		
		//methods[4].invoke(ref);
		
		//其他类中私有的方法
		Class c=Person.class;
		Person ref1=(Person) c.newInstance();
		Method m=c.getDeclaredMethod("test");
		//打开权限
		m.setAccessible(true);
		m.invoke(ref1);
		
		Method m2=c.getDeclaredMethod("testStatic");
		m2.invoke(null);
		
	}

7.获取属性|字段

  1. Field getField(字段名字); 获取公共的指定的字段
  2. Field [] getFields(); 获取公共的所有的字段
  3. Field <T> getDeclaredField(字段名字)获取指定的某个字段
  4. Field [] getDeclaredFields()获取所有的字段(包括私有)
  • 字段对象.SET(对象,字段值);
  • 字段对象获得(对象);

注意:

如果在本类中正常使用。

如果外类中使用私有的,需开放权限:setAccessible(false) - > true(放开)默认false(关闭)

private static void getField() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException{
		Class cls=Class.forName("reflect.ReflectDemo10");  //权限定名=包名+类名
		ReflectDemo10 ref=(ReflectDemo10) cls.newInstance();
		
		Field[] fields=cls.getDeclaredFields();
		for(Field f:fields){
			System.out.println(f.getModifiers());  //获取字段名名字,是所有修饰符代表数字的和
		}
		fields[0].set(ref, "haha");
		//ref.setName("hehe");
		System.out.println(fields[0].get(ref));
		
		System.out.println(ref.getName());
		
		/*Field f=cls.getField("age");
		
		f.set(ref, "10");
		System.out.println(ref.age);*/
		
		//使用Person类中的私有的属性
		Class c=Person.class;
		Person ref1=(Person) c.newInstance();
		Field f=c.getDeclaredField("gender");
		f.setAccessible(true);
		f.set(ref1, 1);
		f.get(ref1);
		//打开权限
		f.setAccessible(false);
		//关闭权限
		System.out.println(f.isAccessible());
	}

8.获取父类的|父接口的的类对象

  1. 子类的类对象.getSuperclass() - 单个   获得父类的Class对象
  2. 子类的类对象.getInterfaces() - 数组    获得父类接口的Class对象
//2.获取父类|父接口的Class对象
	public static void getFu() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
		//1.获取类的Class对象 调用方法  newInstance() 创建对象  调用空构造   空构造一般都给
		Class ref=Class.forName("reflect.ReflectDemo09");
		Class clsFu=ref.getSuperclass();
		//2.创建对象调用方法
		Fu fu=(Fu) clsFu.newInstance();
		fu.test();
		
		Class[] cls=ref.getInterfaces();
		for(Class cl:cls){
			System.out.println(cl);
		}
	}

9.创建类型对象根据类对象

Class对象.newInstance()--->调用空构造
    获取构造器
    构造器对象.newInstance(Class <?> ... parameterTypes);

注意: newInstance()是调用空构造,如果空构造不存在,会出现异常。由此可知,使用其他构造器创建对象比较麻烦,所以确保空构造存在。

//获取源头
Class<?> clz = Class.forName("com.shsxt.ref.simple.User");
//第一种:通过newInstance()创建对象
User user=(User)clz.newInstance();
user.setUname("sxt");
user.setUpwd("good");
//第二种:通过getDeclaredConstructors()创建对象,取得全部构造函数(注意顺序)
Constructor<?>[] cons=clz.getDeclaredConstructors();
for(Constructor<?>c:cons){
    System.out.println(c);
}
// 注意观察上面的输出结果,再实例化,否则参数容易出错
User u1=(User)cons[0].newInstance("shsxt","good");
User u2=(User)cons[1].newInstance("sxt");
User u3=(User)cons[2].newInstance();
System.out.println(u1.getUname()+u1.getUpwd());

10.修饰符

类对象|方法对象|构造器对象|字段对象.getModifiers();

得到修饰符代表数字的和。

//3.,获取修饰符
	 static void getMo() throws ClassNotFoundException{
		//1.获取类的Class对象 调用方法  newInstance() 创建对象  调用空构造   空构造一般都给
		Class ref=Class.forName("reflect.ReflectDemo09");
		int i=ref.getModifiers();
		System.out.println(i);
	}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值