JAVA机制反射是在程序运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2. Java反射的作用有哪些- 在运行时检测对象的类型;动态构造某个类的对象;检测类的属性和方法;任意调用对象的方法;修改构造函数、方法、属性的可见性;
JAVA语言编译之后会生成一个.class文件,反射就是通过字节码文件找到某一个类、类中的方法以及属性等。
反射的实现主要借助四个类:
Class:类的对象
Constructor:类的构造方法
Field:类中的属性对象
Method:类中的方法对象
获取Class类实例
通过子类的Class获得父类
//获得父类 Class c5 = c1.getSuperclass(); System.out.println(c5);
- 所有类型的Class
Class c1 = Object.class;//类 Class c2 = Comparable.class;//接口 Class c3 = String[].class;//一维数组 Class c4 = int[][].class;//二维数组 Class c5 = Override.class;//注解 Class c6 = ElementType.class;//枚举 Class c7 = Integer.class;//基本数据类型 Class c8 = void.class;//void Class c9 = Class.class;//Class
- 获得类信息
Class c1 = Class.forName("com.sun.reflection.User");
//获得类的名字
System.out.println(c1.getName());//获得 包名+类名
System.out.println(c1.getSimpleName());//获得 类名
//获得类的属性
System.out.println("=============================");
//只能找到public属性
Field[] fields = c1.getFields();
for (Field field : fields) {
System.out.println(field);
}
//找到全部属性
Field[] fields2 = c1.getDeclaredFields();
for (Field field : fields2) {
System.out.println(field);
}
//获得类的指定属性
Field name = c1.getDeclaredField("name");
System.out.println(name);
//获得类所有方法
System.out.println("=============================");
//获得本类和父类的public方法
Method[] methods = c1.getMethods();
for (Method method : methods) {
System.out.println("getMethods()"+method);
}
//获得本类所有方法
methods = c1.getDeclaredMethods();
for (Method method : methods) {
System.out.println("getDeclaredMethods()"+method);
}
//获得类的指定方法
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);
System.out.println(getName);
System.out.println(setName);
//获得所有构造器
System.out.println("=============================");
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println("getConstructors"+constructor);
}
constructors = c1.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println("getDeclaredConstructors"+constructor);
}
//获得指定构造器
Constructor constructor = c1.getConstructor(String.class, int.class, int.class);
System.out.println(constructor);
- 通过反射动态创建对象
//获得Class对象
Class c1 = Class.forName("com.sun.reflection.User");
//构造对象
//实际是调用了一个无参构造器
User user = (User) c1.newInstance();
System.out.println(user);
//调用有参构造器
Constructor constructor = c1.getConstructor(String.class, int.class, int.class);
User user2 = (User) constructor.newInstance("Qdong",18,01);
System.out.println(user2);
//通过反射调用普通方法
User user3 = (User) c1.newInstance();
Method setName = c1.getDeclaredMethod("setName", String.class);
//invoke(对象,“方法值”) 激活
setName.invoke(user3,"张三");
System.out.println(user3.getName());
//通过反射操作属性
System.out.println("====================");
User user4 = (User) c1.newInstance();
Field name = c1.getDeclaredField("name");
name.setAccessible(true);//操作私有属性
name.set(user4,"Qdog");
System.out.println(name);
- 通过反射获取泛型
public void test1(Mapmap, List list){ System.out.println("test1"); } public Map test2(){ System.out.println("test2"); return null; } public static void main(String[] args) throws NoSuchMethodException { Method method = ReflectionTest7.class.getMethod("test1", Map.class, List.class); Type[] genericParameterTypes = method.getGenericParameterTypes(); for (Type genericParameterType : genericParameterTypes) { System.out.println("genericParameterTypes"+genericParameterType); //如果这个参数是一个参数化类型,获得真实参数类型 if (genericParameterType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println("actualTypeArgument"+actualTypeArgument); } } } System.out.println("====================="); method = ReflectionTest7.class.getMethod("test2", null); Type genericReturnType = method.getGenericReturnType(); if (genericReturnType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println("actualTypeArgument"+actualTypeArgument); } } }
- 反射操作注解
@TableStu("db_stu")
class Stu{
@FieldStu(columnName = "db_name",type = "varchar",length = 10)
private String name;
@FieldStu(columnName = "db_age",type = "int",length = 10)
private int age;
@FieldStu(columnName = "db_id",type = "int",length = 10)
private int id;
public Stu() {
}
public Stu(String name, int age, int id) {
this.name = name;
this.age = age;
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;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Stu{" +
"name='" + name + ''' +
", age=" + age +
", id=" + id +
'}';
}
}
//类名注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface TableStu{
String value();
}
//属性注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface FieldStu{
String columnName();
String type();
int length();
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("com.sun.reflection.Stu");
//通过反射获得注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获得注解value的值
TableStu tableStu = (TableStu) c1.getAnnotation(TableStu.class);
System.out.println(tableStu.value());
//获得类指定的注解
Field name = c1.getDeclaredField("id");
FieldStu annotation = name.getAnnotation(FieldStu.class);
System.out.println(annotation.columnName());
System.out.println(annotation.length());
System.out.println(annotation.type());
}



