反射
Java反射机制是在程序的运行过程中,对于任何一个类,都能够知道它的所有属性和方法;对于任意一个对象,都能够知道它的任意属性和调用它的任意方法,这个动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
反射机制是Java的动态特性之一(动态语言:在程序运行时,可以改变程序的结构或变量的类型)。Java 不是动态语言,但具有一定的动态性,可以称为”准动态语言”,具备类似动态语言的特性。
反射机制对程序的运行在性能上有一定的影响,速度慢,可以禁止安全检查(setAccessible 启用和禁用访问安全检查,true为不执行安全检查),可以提高反射的运行速度。
常用功能
- 动态的加载类、动态的获取类的信息(属性,方法,构造器)
- 判定对象所属的类
- 动态构造对象
- 动态调用类和对象的任意方法、构造器
- 动态调用和处理属性
- 获取泛型信息
- 处理注解
反射的实现
Java.lang.reflect包实现了反射机制。
获取对象信息
public static void main(String[] args) {
Class car = null;
try {
car = Class.forName("test.reflact.Car");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取对象的所有公共属性
Field[] fields = car.getFields();
//获取对象所有属性,不包含父类的
Field[] declaredFields = car.getDeclaredFields();
}
动态构造对象一
public static void main(String[] args) throws ClassNotFoundException,
IllegalAccessException, InstantiationException {
Class car = Class.forName("test.reflact.Car");
Car c = (Car) car.newInstance();
c.setName("car");
System.out.println(c);
}
动态构造对象二
public static void main(String[] args) throws ClassNotFoundException,
NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class car = Class.forName("test.reflact.Car");
Constructor constructor = car.getConstructor(String.class);
Car c = (Car) constructor.newInstance("car");
System.out.println(c);
}
调用方法
public static void main(String[] args) throws ClassNotFoundException,
NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Class car = Class.forName("test.reflact.Car");
Method method = car.getMethod("toString");
Object c = method.invoke(new Car("car"));
System.out.println(c);
}
反射操作泛型
- ParameterizedType:表示一种参数化的类型 ,比如Collection<String>,可以获取 String信息
- GenericArrayType:泛型数组类型
- TypeVariable:各种类型变量的公共父接口
- WildcardType:代表一种通配符类型表达式,比如? extends Number,? super Integer。(Wildcard 是一个单词,就是通配符)
package test.generic;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class TestGeneric {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
//获取test01方法的泛型参数信息
Class c = TestGeneric.class;
Method test01 = c.getMethod("test01", Map.class, List.class, String.class);
//获取带泛型参数的类型
Type[] tytes = test01.getGenericParameterTypes();
for (Type type : tytes) {
System.out.println(type);
//1.java.util.Map<java.lang.String, java.lang.Integer>
//2.java.util.List<java.lang.Integer>
//3.class java.lang.String 这次不是泛型
if (type instanceof ParameterizedType) {
Type[] genericType = ((ParameterizedType) type).getActualTypeArguments();
//遍历每一个泛型参数中泛型的类型
for (Type genType : genericType) {
//1.1 : 泛型类型:class java.lang.String
//1.2 : 泛型类型:class java.lang.Integer
System.out.println("泛型类型:" + genType);
//2.1 : 泛型类型:class java.lang.Integer
}
}
}
System.out.println("------------------------------");
//获取test02方法返回值的泛型信息
Method m2 = c.getMethod("test02", null);
Type returnType = m2.getGenericReturnType();
System.out.println(returnType);//java.util.Map<java.lang.Integer, java.lang.Integer>
//判断是否带有泛型
if (returnType instanceof ParameterizedType) {
Type[] types = ((ParameterizedType) returnType).getActualTypeArguments();
for (Type type : types) {
System.out.println("返回值的泛型类型:" + type);
//1.返回值的泛型类型:class java.lang.Integer
//2.返回值的泛型类型:class java.lang.Integer
}
}
System.out.println("------------------------------");
Method m3 = c.getMethod("test03", null);
Type returnType3 = m3.getGenericReturnType();
System.out.println(returnType3);//class java.lang.String
System.out.println(returnType3 instanceof ParameterizedType);//false
}
public void test01(Map<String, Integer> map, List<Integer> list, String s) {}
public Map<Integer, Integer> test02() {return null;}
public String test03() {return null;}
}
反射操作注解
package com.annotation.test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import com.annotation.Field;
import com.annotation.Table;
public class Test {
public static void main(String[] args) throws Exception {
//(1)创建Student类的Class对象
Class clazz=Class.forName("com.entity.Student");
//(2)得到Student类的所有注解
Annotation [] annotations=clazz.getDeclaredAnnotations();
for (Annotation a : annotations) {
System.out.println(a);
}
//(3)获取指定的注解
System.out.println("\n----------------------------");
//Table为类上的注解
Table st=(Table) clazz.getDeclaredAnnotation(Table.class);
System.out.println(st);
//(4)获取属性的注解
System.out.println("\n----------------------------");
Field field=clazz.getDeclaredField("stuName");
//Field为属性上的注解
Field sf=field.getDeclaredAnnotation(Field.class);
System.out.println(sf.columnName()+"--"+sf.type()+"--"+sf.length());
}
}
Class类
一个类被加载后,JVM 会创建一个对应类的 Class 对象,类的整个结构信息会被放到Class 对象中。这个Class 对象就像镜子一样,通过这面镜子,可以得到对应类的全部信息。
获取 Class对象的方式
- 对象的getClass()方法:thread.getClass()
- Thread.class
- Class 类的静态方法 forName(….):Class.forName(java.lang.Thread)
![]() | ![]() |
![]() |
Field、Method
![]() | ![]() |
Modifier、ClassLoader
![]() | ![]() |
版权声明:本文为gao_tianLiang原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。






