Java反射基础——四大核心类

反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))

反射就是把java类中的各种成分映射成一个个的Java对象
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。
(其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)
如图是类的正常加载过程:反射的原理在与class对象。
熟悉一下加载的时候:Class对象的由来是将class文件读入内存,并为之创建一个Class对象。

一、反射的操作核心:Object public final native Class<?> getClass():返回Class

二、反射中四大核心类(Class、Constructor、Method、Field)的常用操作方法

2.1、我们先介绍class,它主要就是获取class对象(class<>有类型很多种,要是全部寻找用class<?>通配符,或者确定准确的class<类名>)
我们先创建两个类Teacher和Student做对比,我只放一个,因为一样,这个是整体通用讲解四大核心类需要的class类。

package Reflect;

public class Student {
	private String name;
	private int age;
	
	//修饰符从大到小
	public String a;		//公有
	protected String b;		//保护
	String c;				//默认
	private String d;		//私有
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	public Student() {
	}
	
	public Student(String name,int age) {
		this.name=name;
		this.age=age;
	}
	
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", a=" + a + ", b=" + b + ", c=" + c + ", d=" + d + "]";
	}
	
	public void study() {
		System.out.println("study ");
	}
	
	public void study(String  course) {
		System.out.println("study "+ course);
	}

}
  • **接下来我们学习获取class对象,,创建reflectDemo1 **

  • 获取Class对象的三种方式:
    1. Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象
    * 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
    2. 类名.class:通过类名的属性class获取
    * 多用于参数的传递
    3. 对象.getClass():getClass()方法在Object类中定义着。
    * 多用于对象的获取字节码的方式**

     package Reflect;
     import Reflect.Teacher;
     import Reflect.Student;
    
     public class reflectDemo1 {
    
     	public static void main(String[] args) throws Exception {
     
            Class<?> ct1 = Class.forName("Reflect.Teacher");
     		System.out.println(ct1);
     		
     		Class<?> ct2 = Teacher.class;
     		System.out.println(ct2);
     		
     		Teacher t =new Teacher();
     		Class<?> ct3 = t.getClass();
     		System.out.println(ct3);
     		
     		Class<?> cs1 = Class.forName("Reflect.Student");
     		System.out.println(cs1);
     		
     		Class<?> cs2 = Student.class;
     		System.out.println(cs2);
     		
     		Student s =new Student();
     		Class<?> cs3 = s.getClass();
     		System.out.println(cs3);
     		
     		//获取类名
     		String className1=ct1.getName();
     		System.out.println(className1);
     		String className2=cs1.getName();
     		System.out.println(className2);	
     	}
      }
    

运行结果
在这里插入图片描述2.2、获取成员变量们Field[]的使用,创建reflectDemo2
我们要实现获取class student的成员变量并修改其中成员变量的值
获取成员变量们

  • Field[] getFields() 获取所有public修饰的成员变量
  • Field getField(String name) 获取指定名称的 public修饰的成员变量
  • Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
  • Field getDeclaredField(String name)

操作:

  1. 设置值
    * void set(Object obj, Object value)

  2. 获取值
    * get(Object obj)

  3. 忽略访问权限修饰符的安全检查
    * setAccessible(true):暴力反射

    package Reflect;
    
    import java.lang.reflect.Field;
    
    public class reflectDemo2 {
     
     public static void main(String[] args) throws Exception {
     	//获取Student的class对象
     	Class<?> studentClass = Student.class;
     	/*
     	1. 获取成员变量们
     		* Field[] getFields()	获取所有public修饰的成员变量
     		* Field getField(String name)   获取指定名称的 public修饰的成员变量
    
     		* Field[] getDeclaredFields()  获取所有的成员变量,不考虑修饰符
     		* Field getDeclaredField(String name)
     	*/
     	//Field[] getField()	获取所有public修饰的成员变量
     	Field[] fields=studentClass.getFields();
     	for(Field field:fields) {
     		System.out.println(field);
     	}
     	
     	/*
     	* Field:成员变量
     	* 操作:
     		1. 设置值
     			* void set(Object obj, Object value)  
     		2. 获取值
     			* get(Object obj) 
    
     		3. 忽略访问权限修饰符的安全检查
     			* setAccessible(true):暴力反射
     	*/
     	System.out.println("-------------------");
     	//Field getField(String name)   获取指定名称的 public修饰的成员变量
     	Field a=studentClass.getField("a");
     	//获取成员a的值
     	Student S=new Student();
     	Object value=a.get(S);
     	System.out.println(value);
     	//设置a的值
     	a.set(S,"张三");
     	System.out.println(S);
     	
     	System.out.println("===================");
     	//Field[] getDeclaredFields()  获取所有的成员变量,不考虑修饰符
     	Field[] declaredFields=studentClass.getDeclaredFields();
     	for(Field declaredField:declaredFields) {
     		System.out.println(declaredField);
     	}
     	
     	Field d=studentClass.getDeclaredField("d");
     	//忽略访问权限修饰符的安全检查
     	d.setAccessible(true);//暴力反射
     	d.set(S, "李四");
     	Object value2=d.get(S);
     	System.out.println(value2);
     }
    }
    

结果图
在这里插入图片描述
2.3、构造方法Constructor[]的使用,创建reflectDemo3

我想实现的功能,创建对象,传入参数,再打印对象值
获取构造方法

  • Constructor<?>[] getConstructors()

  • Constructor getConstructor(类<?>… parameterTypes)

  • Constructor getDeclaredConstructor(类<?>… parameterTypes)

  • Constructor<?>[] getDeclaredConstructors()

Constructor:构造方法

  • 创建对象:

  • T newInstance(Object… initargs)

  • 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

      package Reflect;
    
      import java.lang.reflect.Constructor;
    
      public class reflectDemo3 {
    
      public static void main(String[] args) throws Exception {
      //获取Student的class对象
      Class<?> studentClass = Student.class;
      /*
      2. 获取构造方法们
      	* Constructor<?>[] getConstructors()  
      	* Constructor<T> getConstructor(类<?>... parameterTypes)  
    
      	* Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)  
      	* Constructor<?>[] getDeclaredConstructors()  
      */
      
      //Constructor<T> getConstructor(类<?>... parameterTypes)
      Constructor<?> constructor=studentClass.getConstructor(String.class,int.class);
      System.out.println(constructor);
      /*
      * Constructor:构造方法
      	* 创建对象:
      		* T newInstance(Object... initargs) 
      		* 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法 
      */
      
      //创建对象
      Object s=constructor.newInstance("张三",20);
      System.out.println(s);
      
      System.out.println("-------------------");
      Constructor<?> constructor1=studentClass.getConstructor();
      System.out.println(constructor1);
      //创建对象,空参构造
      Object s1=constructor1.newInstance();
      System.out.println(s1);
      
      //空参构造
      Object o=studentClass.newInstance();
      System.out.println(o);
      }
      }
    

结果图:
在这里插入图片描述2.4、执行方法Method[]的使用,创建reflectDemo4
我们要实现执行class student中的函数study(分为无参、有参),以及获取所有public修饰的方法和函数名(会获取一些隐藏的函数名)

package Reflect;

import java.lang.reflect.Method;

public class reflectDemo4 {

public static void main(String[] args) throws Exception {
	//获取Student的class对象
	Class<?> studentClass = Student.class;
	/*
	3. 获取成员方法们:
		* Method[] getMethods()  
		* Method getMethod(String name, 类<?>... parameterTypes)  

		* Method[] getDeclaredMethods()  
		* Method getDeclaredMethod(String name, 类<?>... parameterTypes)
	*/
	//获取执行名称的方法
	Method study_method=studentClass.getMethod("study");
	Student s=new Student();
	
	/*
		* Method:方法对象
		* 执行方法:
			* Object invoke(Object obj, Object... args)
		* 获取方法名称:
			* String getName:获取方法名
	*/
	//执行方法
	study_method.invoke(s);
	
	Method study_method2=studentClass.getMethod("study",String.class);
	//执行方法
	study_method2.invoke(s,"English");
	
	System.out.println("-------------------");
	//获取所有public修饰的方法
	Method[] methods=studentClass.getMethods();
	for(Method method:methods) {
		System.out.println(method);
		String name=method.getName();
		System.out.println(name);
	}
	
}
}

结果图
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值