java基础-反射

1.概念

在程序运行过程中分析类的一种能力(描述类的类)

2.作用

  • 分析类
  • 加载并初始化一个类
  • 查看类的所有属性和方法
  • 查看并使用对象
  • 查看一个对象的所有属性和方法
  • 使用对象的任意属性和方法

类加载器(ClassLoader)

类装载器是用来把类(class)装载进 JVM 的。JVM 规范定义了两种类型的类装载器:启动类装载器(bootstrap)和用户自定义装载器(user-defined class loader)。 JVM在运行时会产生3个类加载器组成的初始化加载器层次结构
在这里插入图片描述

public class ReflectionTest {
	 @Test
	  public void testClassLoader() throws ClassNotFoundException, FileNotFoundException{
   		 
   		 //1. 获取一个系统的类加载器(可以获取,当前这个类PeflectTest就是它加载的)
   		 ClassLoader classLoader = ClassLoader.getSystemClassLoader();
    	 System.out.println(classLoader);
    
  		 //2. 获取系统类加载器的父类加载器(扩展类加载器,可以获取). 
  		 classLoader = classLoader.getParent();
    	 System.out.println(classLoader); 
    		 
  		 //3. 获取扩展类加载器的父类加载器(引导类加载器,不可获取).
  		  classLoader = classLoader.getParent();
  		  System.out.println(classLoader);
    
   		 //4. 测试当前类由哪个类加载器进行加载(系统类加载器): 
   		 classLoader = Class.forName("com.reflect.ReflectionTest") .getClassLoader();
  		 System.out.println(classLoader);

   	    //5. 测试 JDK 提供的 Object 类由哪个类加载器负责加载(引导类)
    	classLoader = Class.forName("java.lang.Object") .getClassLoader();
   		System.out.println(classLoader); 
   }
}
//结果:
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@326de728
null
sun.misc.Launcher$AppClassLoader@18b4aac2
null

负责将类的字节码文件(.class文件)加载到内存中,并生成对应的Class对象

在这里插入图片描述

Class对象

java.lang.Class类的对象,也叫字节码文件对象,每个Class对象对应一个字节码文件

类的加载时机

1).创建实例对象

    Person person = new Person();

2).访问类的静态成员

    Calendar.getInstance();

3).初始化子类

    class User extends Person { }
    User user = new User();//先加载父类

4).反射方式创建类的class对象

    Class clazz = Class.forName("Person");

获取Class对象的三种方式

1).类的静态属性(该方法最为安全可靠,程序性能更高)

   Class clazz = Person.class;      

2).对象的getClass()方法(通常应用在:比如你传过来一个 Object 类型的对象,而我不知道你具体是什么类,用这种方法)

    Person person = new Person();
    Class  clazz = person.getClass();
	
	Object obj = new Person();
    Class  clazz = obj.getClass();

3).Class类的静态方法(用的最多,可能抛异常:ClassNotFoundException)

    Class clazz  = Class.forName("com.reflect.Person");

常用构造器

    Class clazz = Person.class; 
	//1.获取全部构造器
    Constructor[] Constructors = clazz.getConstructors();
   
    //2.获取某一个构造器,需要参数列表
    Constructor<Person> constructor = clazz.getConstructor(String.class, int.class);
    
    //3.调用构造器的 newInstance() 方法创建对象
    Object obj = constructor.newInstance("zhaojie", 1);

常用本类方法

     //1.获取类中的所有方法(包括继承父类的方法),但是获取不到本类私有方法
  	  Method[] methods = clazz.getMethods();
  	  
	 //2.只获取当前类的方法,包括私有方法 
      Method[]  methods = clazz.getDeclaredMethods();

	//3.获取某一个方法(没有入参则不写)
	    method = clazz.getDeclaredMethod("setAge", Integer.class);
   		System.out.println(method);
    //  如果方法用于反射,那么要么int类型( 或者写成 :int.class)写成Integer: public void setAge(Integer age) {  }
  
    //  invoke第一个参数表示执行哪个对象的方法,剩下的参数是执行方法时需要传入的参数
    	Object obje = clazz.newInstance();
    	method .invoke(obje,2);
    	System.out.println("输出getAge方法:"+method );
	 //私有方法的执行,必须在调用invoke之前加上一句method.setAccessible(true);

获取父类方法

Class clazz  = Class.forName("com.reflect.Student");
//获取父类类名
Class superClazz = clazz.getSuperclass();

获取字段

	//获取公用和私有的所有字段,但不能获取父类字段
	Class clazz =  Person.class;
	Field[] fields = clazz.getDeclaredFields();
	//获取指定字段
	Field field = clazz.getDeclaredField("name");

   Person person = new Person("ABC",12);
  // 2.1获取指定对象的指定字段的值
    Object val = field.get(person);
    System.out.println(val);
    
  // 2.2设置指定对象的指定对象Field值
    field.set(person, "DEF");
    System.out.println(person.getName());
    
  // 2.3如果字段是私有的,不管是读值还是写值,都必须先调用setAccessible(true)方法

获取注解

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值