反射
通过反射可以做的事:
- 获取任意类的名称、package信息、所有属性、方法、注解、类型、类加载器等
public class 1213lianxi {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class class1 = Class.forName("com.kuang.reflection.User"); System.out.println("===========================================");
System.out.println(class1.getName()); // 包名 + 类名
System.out.println(class1.getSimpleName()); //类名
System.out.println("===========================================");
//获得字段 :
Field[] fields = class1.getFields(); //只能获得public的属性
System.out.println(fields.length);
Field[] fields2 = class1.getDeclaredFields(); //返回全部的属性,可以获得私有的
System.out.println(fields2.length);
for (Field field : fields2) {
System.out.println("field=>\t"+field);
}
Field name = class1.getDeclaredField("name"); //获取指定的字段!
System.out.println(name);
//获得方法
System.out.println("===========================================");
Method[] methods = class1.getMethods(); //返回当前类和被继承的类的public方法
System.out.println(methods.length);
for (Method method : methods) {
System.out.println("methods: "+method);
}
Method[] declaredMethods = class1.getDeclaredMethods(); //获得当前类的所有方法
System.out.println(declaredMethods.length);
for (Method method : declaredMethods) {
System.out.println("declaredMethods: "+method);
}
System.out.println("=====");
- 获取任意对象的属性,并且能改变对象的属性
public class 1213lianxi {
//创建对象,new 无参,有参!
//通过指定构造器创建对象! new User(1, 3, "lianxi");
public static void main(String[] args) throws Exception {
Class c1 = Class.forName("org.westos.191213demo");
System.out.println("==========================================");
User user1 = (User) c1.newInstance();
System.out.println(user1);
System.out.println("==========================================");
Constructor declaredConstructor = c1.getDeclaredConstructor(int.class, int.class, String.class);
User user2 = (User) declaredConstructor.newInstance(1, 3, "lianxi");
System.out.println(user2);
System.out.println("==========================================");
User user3 = (User) c1.newInstance();
//1. 获得你要操作的方法
Method setName =c1.getDeclaredMethod("setName",String.class);
//2. 通过invoke方法执行方法
setName.invoke(user3,"lhy3");
System.out.println(user3.getName());
System.out.println("==========================================");
User user4 = (User) c1.newInstance();
Field name = c1.getDeclaredField("name");
//显示调用setAccessible为true,则可以访问private方法!
name.setAccessible(true);
name.set(user4,"lhy4");
System.out.println(user4.getName());
}
}
-
调用任意对象的方法
-
判断任意一个对象所属的类
-
实例化任意一个类的对象
import java.lang.annotation.ElementType;
public class Test4 {
public static void main(String[] args) {
Class c1 = Object.class; //class
Class c2 = Comparable.class; //接口
Class c3 = String[].class; // 数组
Class c4 = String[][].class; // 二维数组
Class c5 = ElementType.class; //枚举类型
Class c6 = Override.class; // 注解
Class c7 = Integer.class; //基本数据类型
Class c8 = void.class; //void
Class c9 = Class.class; //反射对象本身
int[] a = new int[10];
String[] b = new String[100];
Class c10 = a.getClass();
Class c11 = b.getClass();
System.out.println(c10);
System.out.println(c11);
System.out.println(c10==c11);
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
System.out.println(c7);
System.out.println(c8);
System.out.println(c9);
}
}
分析性能问题
public class 1214lianxi {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
test3();
}
public static void test1(){
User user = new User();
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000000L ; i++) {
user.getName();
}
long end = System.currentTimeMillis();
System.out.println("普通方法调用执行10亿次:"+(end-start)+"ms"); //558ms
}
public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class class1 = user.getClass();
Method getName = class1.getDeclaredMethod("getName", null);
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000000L ; i++) {
getName.invoke(user,null);
}
long end = System.currentTimeMillis();
System.out.println("反射方法调用执行10亿次:"+(end-start)+"ms"); //3883ms
}
public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class class1 = user.getClass();
Method getName = class1.getDeclaredMethod("getName", null);
getName.setAccessible(true);
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000000L ; i++) {
getName.invoke(user,null);
}
long end = System.currentTimeMillis();
System.out.println("反射方法调用执行10亿次:"+(end-start)+"ms"); //2400ms
}
}
通过代码可以得知,反射的性能消耗很大!