概述
反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的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)
操作:
-
设置值
* void set(Object obj, Object value) -
获取值
* get(Object obj) -
忽略访问权限修饰符的安全检查
* 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);
}
}
}
结果图
最后
以上就是美满大碗为你收集整理的Java反射基础——四大核心类的全部内容,希望文章能够帮你解决Java反射基础——四大核心类所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复