在运行时,对任意一个类都可以获取其属性 方法构造等(类结构);对任意对象都能对属性进行赋值,对方法进行执行,可以操作类。这种动态获取类信息以及动态对类进行操作的机制称之为反射机制。(reflect)
例如:
Person person = new Person(100,"张三");
Person p = new Student();
编译的时候p是person类。运行的时候是student类型。
Class类:存储的是类的结构——反射中有一个核心类:Class
- Class类的类表示正在运行的Java应用程序中的类和接口。
Filed类:类的属性
Method类:类的方法
Constructor类:类的构造方法
Annotation:注解
//Class对象 属性:每一个属性都是一个对象 Filed 方法:也是一个对象Method
2.反射相关类| 类名 | 说明 |
| Class类 | 代表类的实体,在运行的Java应用程序中表示类和接口 |
| Field类 | 代表类的成员变量(成员变量也称为类的属性) |
| Method类 | 代表类的方法 |
| Constructor类 | 代表类的构造方法 |
| Annotation类 | 代表注解 |
Class代表类的实体,在运行的Java应用程序中表示类和接口。在这个类中提供了很多有用的方法,这里对他们简单的分类介绍。
获取Class类三种方式
1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
Class clas1=Class.forName("com.zyk.demo1.Student");
2. 类名.class:通过类名的属性class获取 多用于参数的传递
Classclas2= Student.class;
3. 对象.getClass():getClass()方法在Object类中定义着。 多用于对象的获取字节码的方式
Student student =new Student(); Class clas3=student.getClass();
总结 :同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
获取类的基本信息的方法
- getName():获得类的完整路径名字
- newInstrance():创建类的实例
- getPackage():获得类的包
- getSimpleName():获得类的名字
- getSuperClass():获得当前类继承的父类的名字
- getAnnotation():获取类上面的注解
- getInterfaces():获得当前类实现的类或者是接口
示例代码
public class ReflectDemo2 {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Class student =Student.class;
String name=student.getName();
System.out.println(name);
Object studen1=student.newInstance();
System.out.println(studen1);
Package aPackage = student.getPackage();
System.out.println(aPackage);
String sname=student.getSimpleName();
System.out.println(sname);
//获取类上的注释
Annotation[] annotations = student.getAnnotations();
for (int i = 0; i < annotations.length; i++) {
Annotation annotation = annotations[i];
}
Class superclass = student.getSuperclass();
System.out.println(superclass);
Class[] interfaces = student.getInterfaces();
System.out.println(interfaces);
}
2.2Field类
获得类中属性的方法
| 方法 | 说明 |
| Field getField(String name) | 获取public修饰的成员变量 |
| Field[] getFields() | 获取所有public修饰的成员变量 |
| Field getDeclaredField(String name) | 获取指定的的成员变量 |
| Field []getDeclaredFields() | 获取所有的成员变量,不考虑修饰符 |
Field类中的方法
| 方法 | 说明 |
| void set(Object obj, Object value) | 设置值 |
| get(Object obj) | 获取值 |
| setAccessible(true) | 暴力反射 |
示例代码
public class ReflectDemo3 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
//获取属性对象
Class student = Student.class;
//获取所有变量,不考虑修饰符
Field name = student.getDeclaredField("name");
//获取公有属性
Field address = student.getField("address");
//获取所有public修饰的成员变量
Field[] fields = student.getFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
System.out.println(field);
}
Field[] declaredFields = student.getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++) {
Field declaredField = declaredFields[i];
}
//判断两个field属性是否相等
Student student1=new Student();
//1.获取class对象
Class clas=student1.getClass();
//2.获取属性
Field name2=clas.getDeclaredField("name");
//3.临时赋权限,暴力反射
name2.setAccessible(true);
//4.设置值
name2.set(student1,"hello");
//5.获取对象
Object stu=name2.get(student1);
System.out.println(stu);
}
}
2.3Method类
执行方法:
- Object invoke(Object obj, Object... args)
获取方法名称:
- String getName:获取方法名
获取类中的方法的方法
| 方法名 | 说明 |
| Method[] getMethods() | 获取所有公有方法 |
| Method getMethod(String name, 类>... parameterTypes) | 获取指定公有方法 |
| Method[] getDeclaredMethods() | 获取所有方法 |
| Method getDeclaredMethod(String name, 类>... parameterTypes) | 获取指定方法,不考虑修饰符 |
示例代码
public class ReflectDemo4 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//获取属性对象
Class student = Student.class;
//获取公有方法
Method[] declaredMethods = student.getDeclaredMethods();
for (int i = 0; i < declaredMethods.length; i++) {
Method declaredMethod = declaredMethods[i];
System.out.println(declaredMethod);
}
Method eat = student.getDeclaredMethod("eat",null);
System.out.println(eat);
Method method3 = student.getDeclaredMethod("method3", String.class, int.class);
System.out.println(method3);
Student student1=new Student();
//必须是Object类型(如果有返回值的话)
Object kk=method3.invoke(student1,"hrlo",3);
System.out.println(kk);
}
}
2.4Constructor类
创建对象:
- T newInstance(Object... initargs)
- 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
获取类中构造方法的方法
| 方法 | 说明 |
| Constructor>[] getConstructors() | 获取所有公有构造方法 |
| Constructor | 获取指定公有构造方法 |
| Constructor | 获取指定构造方法,不考虑修饰符 |
| Constructor>[] getDeclaredConstructors() | 获取所有构造方法 |
代码示例
public class ConstractorTest {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class student = Student.class;
Constructor constructor = student.getDeclaredConstructor(String.class);
//强制反射
constructor.setAccessible(true);
//返回值类型是Object
Object student1 = constructor.newInstance("张三");
System.out.println(student1);
}
}
2.5Annotation类
可以参考另一篇博客进行学习,下面是链接地址
java注解使用(Annotation)_爱笑的pig的博客-CSDN博客
这里讲一下使用案例:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnn {
int id();
}
@MyAnn(id=1000)
public class Student extends Person implements aaa{...省略了}
public class TestAnn {
public static void main(String[] args) {
Class aClass = Student.class;
MyAnn ann=aClass.getAnnotation(MyAnn.class);
System.out.println(ann.id());
}
}
2.6Student类
@MyAnn(id=1000)
public class Student extends Person implements aaa{
//成员变量:一个私有,一个默认,一个公共
private String name;
int age;
public String address;
//构造方法:一个私有,一个默认,两个公共
public Student() {
}
private Student(String name) {
this.name = name;
}
Student(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println("我爱吃香蕉");
}
public Student(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
//成员方法:一个私有,四个公共
private void function() {
System.out.println("function");
}
public void method1() {
System.out.println("method");
}
public void method2(String s) {
System.out.println("method:" + s);
}
public String method3(String s, int i) {
return s + "," + i;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + ''' +
", age=" + age +
", address='" + address + ''' +
'}';
}
}



