1、反射获取类对象的三种方式
2、反射获取类字段
3、反射获取类方法、注解
4、方法反射
5、泛型与反射
示例:
public class ReflectClass {
private String a = "11";
private int w = 11;
private String getA(int b) {
return b+"3";
}
@RequestMapping
public double getB(double c) {
return c;
}
protected Long getC(Long d) {
return d;
}
public static void main(String[] args) {{
/**
* 获取类对象的三种方式
* 1、根据该对象获取class
* 2、根据该类获取静态成员变量class
* 3、根据类全路径
*/
DemoClass demoClass = new DemoClass();//静态加载类 编译时加载类---对象
//1
Class c1 = demoClass.getClass();
//2
Class c2 = DemoClass.class;
System.out.println(c1 == c2);
//3
Class c3 = null;
try {
c3 = Class.forName("com.example.demo.controller.DemoClass");//动态加载类 运行时加载类
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(c2 == c3);
Class c5 = int.class;
Class c6 = Integer.class;
Class c7 = String.class;
System.out.println("int: "+c5.getSimpleName()+" Integer: "+c6.getSimpleName());
System.out.println(c7.getSimpleName());
/**
* 获取类字段
*/
System.out.println("getDeclaredFields 本类所有的字段 ==================");
Class c8 = ReflectClass.class;
Field[] fields = c8.getDeclaredFields();//获取类的字段
for (Field field: fields) {
System.out.print(field.getType().getSimpleName()+" ");//获取类的字段变量的类型 --> String
System.out.print(field.getName()+",");//获取类的字段的名称 --> a
}
/**
* 获取类方法
*/
System.out.println("\nMethods 本类及父类 public 方法 ==================");
Method[] methods = c8.getMethods();//获取类的所有 公共 方法
Method[] declaredMethods = c8.getDeclaredMethods();//获取本类的所有的方法
for (Method method: methods) {
System.out.print(method.getName() + " ");
}
System.out.println("\ndeclaredMethods 本类的所有的方法 ==================");
for (Method method: declaredMethods) {
System.out.print(method.getName()+" ");
}
System.out.println("\nParameters 本类的所有的方法的参数名 及参数类型 ==================");
for (Method method: declaredMethods) {
System.out.print(method.getParameters()[0].getName()+":");//获取本类所有方法的参数的名称 args b b
System.out.print(method.getParameters()[0].getType().getSimpleName()+" ");//获取本类所有方法的参数的类型
}
System.out.println("\ngetDeclaredAnnotations 获取所有方法的注解名称==================");
for (Method method: declaredMethods) {
System.out.print(method.getName()+":");//获取所有方法的名称 args b b
//获取声明方法的注解名称 args b b
System.out.print(method.getDeclaredAnnotations().length>0 ? (method.getDeclaredAnnotations()[0].annotationType().getSimpleName()+" "):" ");//获取声明方法的
}
System.out.println("\n方法反射==================");
Method m = null;
try {
m = ReflectClass.class.getDeclaredMethod("getA",int.class);//获取一个方法
Object o = m.invoke(new ReflectClass(),2);//反射操作方法
System.out.println(o);
} catch (IllegalAccessException | NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println("\n泛型==================");
List<String> lists = new ArrayList<>();
lists.add("1111");
List<Integer> listi = new ArrayList<>();
System.out.println(lists.getClass() == listi.getClass());//true
/*
* 结论说明:反射的操作都是编译后的操作
* java 的泛型只在编译阶段有效,是为了防止输入错误,绕过了编译就没有错误;
*/
//绕过编译,绕过泛型
System.out.println("\n绕过编译,绕过泛型==================");
try {
Method list = lists.getClass().getMethod("add",Object.class);
list.invoke(lists,2.55);//在泛型为string的list中加入double类型数据
System.out.println(lists);//[1111, 2.55]
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
class DemoClass{}