概述:
动态语言:类在运行时可以改变其结构的语言。
Java利用反射机制可以获得类似动态语言的特性。
获取类对象的方式
-
若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高
Class clazz = Person.class;
-
已知某个类的实例,调用该实例的getClass()方法获取Class对象
Class clazz = Person.getClass();
-
已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取
Class clazz = Class.forName(“com.demo.Person”);
注意:一个对象只有一个class对象
通过反射获取类的信息
类名:Name、属性:Field、方法:Method、
构造器:Constructor、父类:Superclass、接口:Interface、注解:Annotation
Declared :获取本类全部的***,包括私有的
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException {
Class c1 = Class.forName("com.study.annotation.User");
//获取包名+类名
String name = c1.getName();
System.out.println(name);
//获取类名
name = c1.getSimpleName();
System.out.println(name);
System.out.println("=========================");
//获取public类型的属性
Field[] fields = c1.getFields();
for (Field field : fields) {
System.out.println(field);
}
//获取该类的全部属性
fields = c1.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("=========================");
//获取本类和父类的所有的public方法
Method[] methods = c1.getMethods();
System.out.println("获取本类和父类的所有的public方法");
for (Method method : methods) {
System.out.println(method);
}
//获取本类全部的方法
System.out.println("获取本类全部的方法");
methods = c1.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("=========================");
//获取构造器
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
//获取全部构造器
constructors = c1.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("=========================");
//获取父类
Class superclass = c1.getSuperclass();
System.out.println(superclass);
}
}
通过反射动态的创建对象
-
*.newInstance();
-
*.getDeclaredConstructor(String.class,…).newInstance(“Hello”,…);
Class c1 = Class.forName("com.study.annotation.User"); //无参构造 User user1 = (User) c1.newInstance(); System.out.println(user1); //有参构造 Constructor constructor = c1.getDeclaredConstructor(int.class, String.class, int.class); User sai = (User) constructor.newInstance(1, "sai", 18); System.out.println(sai);
invoke(调用)
获取方法后.invoke,使用该方法
Method getName = c1.getDeclaredMethod("getName",null);
String name = (String) getName.invoke(user, null);
System.out.println(name);
.setAccessible(True)跳过安全监测
Field、Method、Constructor,都有setAccessible()方法
setAccessible作用是启动和禁用访问安全检查的开关
Method getName = c1.getDeclaredMethod("getName",null);
getName.setAccessible(true);
String name = (String) getName.invoke(user, null);
System.out.println(name);
性能:普通调用 > 反射调用,关闭检查 > 反射调用
通过反射操作泛型
通过反射获取注解
package com.study.annotation;
import java.lang.annotation.*;
import java.lang.reflect.Field;
/**
* @Author sai
* @Description 通过反射获取注解
* @Time 2020-12-30 10:10
*/
@Sai("通过反射获取注解")
public class Test05 {
@Sai2(type = "int", name = "db_id", length = 8)
private int id;
@Sai2(type = "string", name = "db_name", length = 8)
private String name;
@Sai2(type = "int", name = "db_length", length = 8)
private int age;
public Test05() {
}
public Test05(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Test05{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Sai{
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Sai2{
String name();
String type();
int length();
}
class test{
public static void main(String[] args) throws Exception {
Class c = Class.forName("com.study.annotation.Test05");
Annotation[] annotations = c.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
Sai annotation = (Sai)c.getAnnotation(Sai.class);
String value = annotation.value();
System.out.println(value);
Field name = c.getDeclaredField("name");
Sai2 annotation1 = name.getAnnotation(Sai2.class);
System.out.println(annotation1.type());
System.out.println(annotation1.name());
System.out.println(annotation1.length());
}
}