1、定义
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。 --百度百科
就是可以在运行时动态的加载和使用编译时不知道的Class,也就是说我可以在运行时指定处理哪一个类,然后获取它的构造器或者fields或者mathod
2、使用途径
动态加载类 动态获取类的信息 (方法 属性 构造器)
动态构造对象
动态调用和处理属性
获取泛型信息
处理注解
3、内容
与反射相关的类大概有如下几种
Class | 代表类的实体,在程序运行中表示类和接口 |
Field | 代表类的属性 |
Method | 代表类的方法 |
Constructor | 代表了类的构造器 |
Class
获得类的相关方法
getDeclareClass() | 返回一个数组,该数组中包含所有的类和接口对象 |
getClasses() | 返回一个数组,数组中包含该类中所有公共类和接口类的对象 |
forName(String className) | 根据类名返回类的对象 |
getName() | 获得类的完整路径名字 |
newInstance() | 创建类的实例 |
getPackage() | 获取类的包 |
getSimpleName() | 获得类的名字 |
getSuperclass() | 获得当前类继承的父类的名字 |
getInterfaces() | 获得当前类实现的类或者接口 |
Class.forName( )方法的目的是为了动态加载类。这仅是加载,还没有实例化,所以不能用,
一般还要调用Class下的newInstance( )静态方法来实例化对象以便操作。
简单实现:
package reflectDemo;
import java.util.Arrays;
public class ReflectTest {
//公有内部类
public class public_class
{
}
//私有内部类
private class private_class
{
}
//公有接口
public interface public_interface
{
}
//私有接口
private interface private_interface
{
}
public static void main(String[] args) {
try {
Class c=Class.forName("reflectDemo.ReflectTest");
Class[] classes=c.getClasses();//返回类中公有内部类和接口信息
for (Class class1 : classes) {
System.out.println(class1.getSimpleName());//输出内部类的名字
}
System.out.println("-----------------");
classes=c.getDeclaredClasses();
//获取所有的内部类和接口
for (Class class1 : classes) {
System.out.println(class1.getSimpleName());//输出内部类的名字
}
System.out.println("类的包名"+c.getPackage());
System.out.println("类的父类为"+c.getSuperclass());
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
实现结果:
public_class
public_interface
-----------------
private_class
private_interface
public_class
public_interface
类的包名package reflectDemo
类的父类为class java.lang.Object
获得类属性的相关方法
getField(String name) | 获得某个公有属性 |
getFields() | 获得所有的公有的属性 |
getDeclaredField(String name) | 获得某个类属性(包括私有) |
getDeclaredFields() | 获得所有的属性 |
简单实现:
package reflectDemo;
import java.lang.reflect.Field;
import java.util.Arrays;
public class ReflectTest {
public User sUser;
public String string;
//公有属性
private String fString;
private int age ;
private Student student;
//私有属性
protected String string2;
private int cage;
public static void main(String[] args) throws NoSuchFieldException, SecurityException {
try {
Class class1=Class.forName("reflectDemo.ReflectTest");
Field field=class1.getField("sUser");
System.out.println("属性的名字为"+field.getName());
System.out.println("----------------");
Field field2=class1.getDeclaredField("fString");
System.out.println("属性的名字为"+field2.getName());
System.out.println("----------------");
Field[] fields=class1.getDeclaredFields();
//获取所有声明的属性
for (Field field3 : fields) {
System.out.println("属性的名字为"+field3.getName());
}
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
实现结果:
属性的名字为sUser
----------------
属性的名字为fString
----------------
属性的名字为sUser
属性的名字为string
属性的名字为fString
属性的名字为age
属性的名字为student
属性的名字为string2
属性的名字为cage
获得类中注解相关的方法
getAnnotation(Class<A> annotationClass) | 返回该类中与参数类型匹配的公有注解对象 |
getAnnotations() | 返回该类所有的公有注解对象 |
getDeclaredAnnotation(Class<A> annotationClass) | 返回该类中与参数类型匹配的所有注解对象 |
getDeclaredAnnotations() | 返回该类所有的注解对象 |
简单实现:
package reflectDemo;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
@SqlDataBase(DataBaseName="myDataBase")
@Sqltable(table_name="Student")
public class ReflectTest {
@SqlField(type="varchar",name="StudentName",length=10)
private String name;
@SqlField(type="int",name="Studentage",length=10)
private int age;
@SqlField(type="int",name="Studentgrade",length=10)
private String grade;
public static void main(String[] args) {
Class class1 = null;
try {
class1 = Class.forName("reflectDemo.ReflectTest");
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
//类上的注解
Annotation[] annotations=class1.getDeclaredAnnotations();
//返回该类的所有的注解注意并不包括字段和方法上的注解
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
try {
Field[] field=class1.getDeclaredFields();
for (Field field2 : field) {
Annotation[] annotation=field2.getAnnotations();
for (Annotation annotation2 : annotation) {
System.out.println("注解的信息为"+annotation2);
}
}
} catch (SecurityException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
实现结果:
@reflectDemo.SqlDataBase(DataBaseName=myDataBase)
@reflectDemo.Sqltable(table_name=Student)
注解的信息为@reflectDemo.SqlField(type=varchar, name=StudentName, length=10)
注解的信息为@reflectDemo.SqlField(type=int, name=Studentage, length=10)
注解的信息为@reflectDemo.SqlField(type=int, name=Studentgrade, length=10)
获得类中构造器相关的方法
getConstructor(Class...<?> parameterTypes) | 获得该类中与参数类型匹配的公有构造方法 |
getConstructors() | 获得该类的所有公有构造方法 |
getDeclaredConstructor(Class...<?> parameterTypes) | 获得该类中与参数类型匹配的构造方法 |
getDeclaredConstructors() | 获得该类所有构造方法 |
这里传入参数来确定构造方法考虑到了重载的问题
简单实现:
package reflectDemo;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflectTest {
private String name;
private int age;
private String grade;
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 String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public ReflectTest()
{
}
public ReflectTest(String name,int age)
{
}
public ReflectTest(String name,int age,String grade)
{
System.out.println("这是拥有三个");
this.age=age;
this.name=name;
this.grade=grade;
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
try {
Class class1=Class.forName("reflectDemo.ReflectTest");
Constructor constructor=class1.getConstructor(String.class,int.class,String.class);
Object cObject= constructor.newInstance("扬弟弟",18,"100");
ReflectTest reflectTest=(ReflectTest)cObject;
System.out.println("年龄为"+reflectTest.getAge());
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
实现结果:
这是拥有三个参数的方法
年龄为18
获得类中方法相关的方法
getMethod(String name, Class...<?> parameterTypes) | 获得该类某个公有的方法 |
getMethods() | 获得该类所有公有的方法 |
getDeclaredMethod(String name, Class...<?> parameterTypes) | 获得该类某个方法 |
getDeclaredMethods() | 获得该类所有方法 |
简单实现:
package reflectDemo;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectTest {
private String name;
private int age;
private String grade;
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 String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public void function1(String name)
{
System.out.println("参数为1个");
}
public void function1(String name,int age)
{
System.out.println("参数为2个");
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException {
Class class1=Class.forName("reflectDemo.ReflectTest");
//获取声明的所有的方法
Method[] methods=class1.getDeclaredMethods();
//Method[] methods=class1.getMethods();//获取公有的所有的方法
for (Method method : methods) {
System.out.println("方法的名字为"+method.getName()+"---方法的参数总数为"+method.getParameterCount());
}
Method method=class1.getMethod("function1", String.class,int.class);
ReflectTest reflectTest=(ReflectTest) class1.newInstance();
method.invoke(reflectTest, "扬弟弟",10);
//通过反射调用相关的方法
}
}
实现结果:
方法的名字为main---方法的参数总数为1
方法的名字为getName---方法的参数总数为0
方法的名字为setName---方法的参数总数为1
方法的名字为setGrade---方法的参数总数为1
方法的名字为getAge---方法的参数总数为0
方法的名字为getGrade---方法的参数总数为0
方法的名字为function1---方法的参数总数为2
方法的名字为function1---方法的参数总数为1
方法的名字为setAge---方法的参数总数为1
参数为2个
类中其他重要的方法
isAnnotation | 如果是注解类型则返回true |
isAnnotationPresent(Class<? extends Annotation> annotationClass) | 如果是指定类型注解类型则返回true |
isAnonymousClass() | 如果是匿名类则返回true |
isArray() | 如果是一个数组类则返回true |
isEnum() | 如果是枚举类则返回true |
isInstance(Object obj) | 如果obj是该类的实例则返回true |
isInterface() | 如果是接口类则返回true |
isLocalClass() | 如果是局部类则返回true |
isMemberClass() | 如果是内部类则返回true |