Java反射使用示例
1、访问构造方法
访问方法 | 返回值类型 | 说明 |
---|---|---|
Class.getConstructors() | Constructor型数组 | 获得所有访问权限为public的构造方法 |
Class.getDeclaredConstructors() | Constructor型数组 | 获得所有构造方法 |
Class.getConstructor(Class<?>…parameterTypes) | Constructor对象 | 获得权限为public的指定构造方法 |
Class.getDeclaredConstructor() | Constructor对象 | 获得指定的构造方法 |
Constructor.getModifiers() | 获得权限修饰符 | |
Constructor.getName() | 构造方法的名字 | |
Constructor.getParameterTypes() | Class[] | 构造方法的参数类型(String,int,double) |
//public T newInstance(Dbjece ...initargs); //Constructor构造对象
/**
Example.java
*/
public class Example {
private int id;
private String name;
private double price;
public Example() {
}
public Example(int id, String name) {
this.id = id;
this.name = name;
}
private Example(int id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
}
public void doIt(){
System.out.println("doIt函数被调用了!");
}
private void add(int x,int y){
System.out.println(x+" + "+y+" = "+(x+y));
}
@Override
public String toString() {
return "Example{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
'}';
}
}
/**
Main.java
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
public class Main {
public static void main(String[] args) {
try {
Class<Example> c = Example.class; //获取一个class对象
Constructor[] constructor = c.getDeclaredConstructors();//获得所有权限的构造函数 getConstructors() 只能获取public的构造函数
for (Constructor con:constructor) { //遍历输出这些构造函数
System.out.print(Modifier.toString(con.getModifiers())+" "); //输出当前构造函数的权限修饰符
System.out.print(con.getName()+"("); //输出函数名字
Class[] paras = con.getParameterTypes(); //获取参数列表
for (int i=0;i<paras.length;i++){ //遍历输出参数列表
System.out.print(paras[i].getSimpleName()+" args "); //获取当前参数修饰符(String,int,double...)
if (i<paras.length-1){
System.out.print(",");
}
}
System.out.println(")");
}
Constructor<Example> cs = c.getDeclaredConstructor(int.class,String.class,double.class); //获取指定的构造函数
cs.setAccessible(true); //获取权限如果不获取权限就只能用public修饰的构造函数
Example obj = cs.newInstance(-1,"胡晓龙",1); //创建一个对象
System.out.println(obj.toString());
obj.doIt();
} catch (NoSuchMethodException e) {
System.out.println("没有找到对应的方法"); //getDeclaredConstructor()可能会引发这个异常
e.printStackTrace();
} catch (InstantiationException e) {
System.out.println("不能实例化对象异常"); //cs.newInstance()可能引发这个异常
e.printStackTrace();
} catch (InvocationTargetException e) {
System.out.println("反射异常"); //cs.newInstance() 可能引发这个异常
e.printStackTrace();
} catch (IllegalAccessException e) {
System.out.println("没有访问权限"); //如果没有cs1.setAccessible(true) 就会已发这个异常
e.printStackTrace();
}
}
}
/**
输出结果
private Example(int args ,String args ,double args )
public Example(int args ,String args )
public Example()
Example{id=-1, name='胡晓龙', price=1.0}
doIt函数被调用了!
*/
2、访问成员变量
访问方法 | 返回值类型 | 说明 |
---|---|---|
Class.getFields() | Field数组 | 获得所有权限为public的成员变量 |
Class.getField() | Field对象 | 获得指定的权限为public的成员变量 |
Class.getDeclaredFields() | Field数组 | 获得所有成员变量 |
Class.getDeclaredField() | Field对象 | 获得指定成员变量 |
Field.getModifiers() | 获得成员变量权限修饰符(public,private) | |
Field.getName() | 获得成员变量的名字 | |
Field.getType() | 获得成员变量的声明类型(String,int,double…) | |
Field.get(Class) | 获取相应Class对象的某一个成员变量值 | |
Field.set(Class,args) | 修改相应Class对象的某一个成员变量值 |
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
public class Main {
public static void main(String[] args) {
Class<Example> exampleClass = Example.class;
Field[] fields = exampleClass.getDeclaredFields();
for (Field field: fields) {
System.out.print(Modifier.toString(field.getModifiers())+" ");
System.out.print(field.getName()+" ");
System.out.print(field.getType().getSimpleName());
System.out.println();
}
try {
Constructor<Example> ex = exampleClass.getDeclaredConstructor(int.class,String.class,double.class);
ex.setAccessible(true);
Field field = exampleClass.getDeclaredField("name");
field.setAccessible(true);
Example example = ex.newInstance(1,"胡晓龙",10);
System.out.println(field.get(example)); //获取example对象的成员变量值
field.set(example,"张前"); //修改example对象的成员变量值
System.out.println(field.get(example));
} catch (NoSuchMethodException e) { //没有找到对应的方法
e.printStackTrace();
} catch (IllegalAccessException e) {
//如果没有field.setAccessible(true) ex.setAccessible(true) 就会已发这个异常
System.out.println("没有访问权限");
e.printStackTrace();
} catch (InstantiationException e) {
System.out.println("不能实例化对象异常"); //ex.newInstance()可能引发这个异常
e.printStackTrace();
} catch (InvocationTargetException e) {
System.out.println("反射异常"); //ex.newInstance() 可能引发这个异常
e.printStackTrace();
} catch (NoSuchFieldException e) { //没有找到对应的成员变量
System.out.println("未找到相应成员变量");
e.printStackTrace();
}
}
}
/**
private id int
private name String
private price double
胡晓龙
张前
*/
3、访问成员方法
访问方法 | 返回值类型 | 说明 |
---|---|---|
Class.getMethods() | Method型数组 | 获得访问权限为public的方法 |
Class.getMethod(String name,Class<?>…parameterTypes) | Method对象 | 获得权限为public的方法name为方法名后面是参数列表 |
Class.getDeclaredMethods() | Method型数组 | 获得所有方法 |
Class.getDEclaredMethod(String name,Class<?>…parameterTypes) | Method对象 | 获得指定方法 |
invoke(Object obj,Object…args) | 调用成员方法 | |
method.getModifiers() | 获取修饰符 | |
method.getName() | 获取方法名 | |
method.getParameterType | Class[] | 获得参数类型列表(String,int,double…) |
import java.lang.reflect.*;
public class Main {
public static void main(String[] args) {
Class<Example> exampleClass = Example.class;
Method[] modifiers = exampleClass.getDeclaredMethods();
for (Method method:modifiers) {
System.out.print(Modifier.toString(method.getModifiers())+" ");
System.out.print(method.getName()+"(");
Class[] classes = method.getParameterTypes();
for (int i=0 ;i<classes.length;i++){
System.out.print(classes[i]+" args");
if (i<classes.length-1){
System.out.print(",");
}
}
System.out.println(")");
}
try {
Constructor<Example> exampleConstructor = exampleClass.getDeclaredConstructor(int.class,String.class,double.class); //获取指定的构造函数
exampleConstructor.setAccessible(true);
Example example = exampleConstructor.newInstance(1,"胡晓龙",2);
Method method = exampleClass.getDeclaredMethod("add",int.class,int.class);
method.setAccessible(true);
method.invoke(example,1,2); //调用方法
} catch (NoSuchMethodException e) {
//未找到方法异常
e.printStackTrace();
} catch (InstantiationException e) {
System.out.println("不能实例化对象异常"); //cs.newInstance()可能引发这个异常
e.printStackTrace();
} catch (InvocationTargetException e) {
System.out.println("反射异常"); //cs.newInstance() 可能引发这个异常
e.printStackTrace();
} catch (IllegalAccessException e) {
System.out.println("没有访问权限"); //如果没有cs1.setAccessible(true) 就会已发这个异常
e.printStackTrace();
}
}
}
/**
private add(int args,int args)
public toString()
public doIt()
1 + 2 = 3
*/
3、使用Annotation创建自定义注解符号
public @interface MyAnnotation{
String value() default "默认值"; //String:成员类型。可用的成员变量类型有String、Class、primitive、enumerated和annotation...
Class type() default void.class; //default "默认值"
}
元注解
注解符 | 功能 |
---|---|
@Decumented | 指示某一类型的注解通过javadoc和类似的默认工具进行文档初始化 |
@Inherited | 指示注释类型被自动继承 |
@Rectention | 指示注解类型的注释要保留多久 |
@Target | 指示注释类型所适应的程序元素的种类 |
@Retention
枚举常量 | 说明 |
---|---|
SOURCE | 不编译Annotation到类文件中 |
CLASS | 编译Annotation到类文件中,运行时不加载 |
RUNTIME | 在运行时加载到JVM中(运行时能看到,反射注解的前提) |
@Target
枚举常量 | 说明 |
---|---|
ANNOTATION_TYPE | 用于Annotation类型 |
TYPE | 用于类、接口和枚举,以及Annotation类型 |
CONSTRUCTOR | 用于构造方法 |
FIELD | 用于成员变量和枚举常量 |
METHOD | 用于方法 |
PARAMETER | 用于参数 |
LOCAL_VARIABLE | 用于局部变量 |
PACKAGE | 用于包 |
方法 | 说明 |
---|---|
isAnnotationPresent(Class annotationClass) | 查看是否添加了指定的注解 |
getAnnotation(Class annotationClass) | 获取指定的注解 |
getAnnotation() | 获取所有注解的数组 |
/**
MyAnnotation.java
*/
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "默认值";
Class type() default void.class;
}
/**
Main.java
*/
import java.lang.reflect.Field;
public class Main {
public static void main(String[] args) {
Class<Student> studentClass = Student.class;
Field[] fields = studentClass.getDeclaredFields();
for (Field field:fields) {
if (field.isAnnotationPresent(MyAnnotation.class)){
MyAnnotation myAnnotation =field.getAnnotation(MyAnnotation.class);
System.out.print( field.getName()+"已经被注解了! ");
System.out.println("注解内容为:"+myAnnotation.value());
}
}
}
}
/**
id已经被注解了! 注解内容为:学生的ID
name已经被注解了! 注解内容为:学生的名字
*/