反射
通过某种机制,动态的得到,调用类的所有信息(属性,方法)。
反射的使用
1.得到类的Class对象
类名.class
类的对象.getClass()
常用: 通过Class类的static方法:forName(类的全限定名);全限定名:包名。类名
2.通过Class类对象得到类的所有信息
3.通过Class类对象调用类的所有信息
import java.lang.reflect.*;
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
StringBuilder s = new StringBuilder();
Class aClass = Class.forName("Student");
//aClass.getModifiers()获取对应的修饰符 返回类型是int类型的所以要通过Modifier.toString的方法来转换为字符串
//aClass.getSimpleName()当前类名
s.append(Modifier.toString(aClass.getModifiers())+" class "+aClass.getSimpleName()+"{\n");
//获取当前类的所有属性
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
s.append("\t");
//field.getModifiers()获取属性的修饰符
s.append(Modifier.toString(field.getModifiers()));
if (field.getModifiers()!=0) s.append(" ");
//field.getType().getSimpleName()获取属性的返回值
s.append(field.getType().getSimpleName()+" ");
//field.getName()获取属性的名字
s.append(field.getName()+";\n");
}
s.append("\n");
//获取构造方法
Constructor[] constructors = aClass.getDeclaredConstructors();
for (Constructor constructor : constructors) {
s.append("\t");
s.append(Modifier.toString(constructor.getModifiers()) + " ");
s.append(constructor.getName()+"(");
Class[] parameterTypes = constructor.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
s.append(parameterTypes[i].getSimpleName());
if (i!= parameterTypes.length-1) s.append(",");
}
s.append(") {}\n");
}
/**
* aClass.getMethods()获取当前类的所有方法
* method.getReturnType().getSimpleName() 方法返回值类型
* method.getParameterTypes() 获取当前方法的所有参数类型
*/
Method[] methods = aClass.getMethods();
for (Method method : methods) {
s.append("\t");
s.append(Modifier.toString(method.getModifiers())+" ");
s.append(method.getReturnType().getSimpleName()+" ");
s.append(method.getName());
s.append(" ( ");
Class<?>[] parameterTypes = method.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
s.append(parameterTypes[i].getSimpleName());
if (i!= parameterTypes.length-1) s.append(",");
}
s.append(") {}\n");
}
s.append("}");
System.out.println(s);
}
}
反射还可以得到注解的值
自定义注解
//自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value =ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Role {
String role();
}
对象类
//商品类
public class Goods {
@Role(role = "管理员")
public void Put(){
System.out.println("商品上架");
}
@Role(role = "顾客")
public void Buy(){
System.out.println("是否购买此商品");
}
public void Look(){
System.out.println("查看商品");
}
}
测试类
//Test类
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Scanner;
public class Test {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Scanner input =new Scanner(System.in);
System.out.println("请输入你的角色:");
String role = input.next();
System.out.println("请输入调用的方法:");
String method = input.next();
Goods goods = new Goods();
Class<? extends Goods> aClass = goods.getClass();
Method declaredMethod = aClass.getDeclaredMethod(method);
//判断方法上是否有注解
if (declaredMethod.isAnnotationPresent(Role.class)){
//获取方法上的注解对象
Role annotation = declaredMethod.getAnnotation(Role.class);
String role1 = annotation.role();
if (role1.equals(role)){
System.out.println("有权限");
declaredMethod.invoke(goods);
}else {
System.out.println("无权限");
}
}else {
System.out.println("有权限");
declaredMethod.invoke(goods);
}
}
}
反射的作用
开发通用框架 - 反射最重要的用途就是开发各种通用框架。. 很多框架(比如 Spring)都是配置化的(比如通过 XML 文件配置 JavaBean、Filter 等)