反射

tech2024-02-22  73

java反射机制 java反射机制是一种动态机制,它允许我们加载一个类实例化一个类,调用方法或操作属性从编码期间确定转为在运行期间确定。 这样做可以大大提高代码的灵活度,但是反射有更大的资源开销。所以不能过度依赖反射。

Class 用来描述类本身

Class类 Class类的每一个实例用于表示JVM已经加载的一个类。并且在JVM内部每个被加载的类都有且只有一个Class的实例与之对应。通过类对象我们可以: 获取其表示的类的名字,构造方法,方法,属性,并可以快速实例化。

获取一个类的类对象有以下方式: 1:直接通过类的静态属性class得到。 比如像获取String的类对象,我们可以: Class cls = Person.class;

2:通过Class的静态方法forName加载: Class cls = Class.forName(“java.lang.String”);

3:通过类加载器ClassLoader 对象.getClass();

Package 类中的包

Field 用来描述类中的属性

Method 描述类中的方法

Constructor 类的构造方法

Annotation 类中的注解

public static void main(String[] args) { try { //获得类的三种方法 System.out.println(Class.forName("atm.Test$Person")); System.out.println(Person.class); System.out.println(new Test().new Person().getClass()); Class clazz1 = Class.forName("atm.Test$Person"); System.out.println("类的修饰符"+clazz1.getModifiers());; Class clazz = Class.forName("java.util.ArrayList"); System.out.println(clazz); System.out.println(ArrayList.class); System.out.println(new ArrayList<String>().getClass()); System.out.println("类的修饰符"+clazz.getModifiers()); System.out.println("类的名字有包"+clazz.getName()); System.out.println("类的名字"+clazz.getSimpleName()); Package package1 = clazz.getPackage(); System.out.println("类所在的包"+package1.getName()); Class class1 = clazz.getSuperclass(); System.out.println("父类"+class1); Class[] classes = clazz.getInterfaces(); for (Class class2 : classes) { System.out.println("实现的接口"+class2); } //相当于调用无参数构造方法创建对象,如果没有无参数构造方法,会抛出异常 Object object = clazz.newInstance(); //获取类的属性,只能看到public修饰的 Class class3 = Atm.class; Atm atm = (Atm) class3.newInstance(); Field field = class3.getField("size"); //属性的修饰符 System.out.println(field.getModifiers()); //属性的类型 System.out.println(field.getType()); //属性的名字 System.out.println(field.getName()); //给属性赋值 field.set(atm, "张三"); //取出属性的值 System.out.println(field.get(atm)); //获取类中的所有属性,自己的和父类的所有public的 Field[] fields = class3.getFields(); for (Field field2 : fields) { System.out.println(field2); } //获得其他权限修饰符的属性 Field field1 = class3.getDeclaredField("age"); //修改属性被操作的状态(允许私有属性被赋) field1.setAccessible(true); field1.set(atm, 1); System.out.println(field1.get(atm)); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { //通过反射修改String的不可变特性 try { String string = "李四"; Class clazz1 = String.class; Field value = clazz1.getDeclaredField("value"); value.setAccessible(true); //获取value的内存地址 char[] cs = (char[])value.get(string); cs[0]='张'; cs[1]='三'; System.out.println(string); } catch (Exception e) { e.printStackTrace(); } }

获取类中的方法

public static void main(String[] args) { Class clazz = Atm.class; //获取类中的所有方法 //获取自己类和父类的所有public方法 Method[] methods = clazz.getMethods(); System.out.println(methods); try { //根据方法名字获得类中的一个方法 //根据名字获取自己类和父类的所有public方法 Method method = clazz.getMethod("eat"); //........ int a = method.getModifiers(); Class b = method.getReturnType(); String c = method.getName(); Class[] d = method.getParameterTypes(); Class[] e = method.getExceptionTypes(); //调用方发执行 method.invoke(clazz.newInstance()); //获得有参数的方法并执行 Method method2 = clazz.getMethod("eat", int.class,String.class); Object object = method2.invoke(clazz.newInstance(), 10,"张三"); System.out.println((Integer)object); //获得其他修饰符的方法 Method method3 = clazz.getDeclaredMethod("slep"); //此时不能直接赋值,需要设置方法的准入权 method3.setAccessible(true); method3.invoke(clazz.newInstance()); } catch (Exception e) { e.printStackTrace(); } }

获取类中的构造方法

public static void main(String[] args) { try { Class clazz = Atm.class; clazz.getConstructors(); Constructor cons = clazz.getConstructor(); //执行构造方法 cons.newInstance(); Constructor cons1 = clazz.getConstructor(String.class,Integer.class); cons1.newInstance("张三",111); } catch (Exception e) { e.printStackTrace(); } }
最新回复(0)