写点什么

Java 反射

作者:卢衍飞
  • 2022-11-25
    山东
  • 本文字数:12599 字

    阅读完需:约 41 分钟

Java 反射

Java 反射表示重要反射机制问题这种方法贼牛 X,也就是通过外部文件配置,在不修改源码的情况下,来控制程序,也符合设计模式的 ocp 原则(开闭原则:不修改源码,扩容功能)


可以通过修改 properties 配置文件的 method 的配置,实现修改程序的表现方式。


举例子:


src\re.properties 文件


classfullpath = opp3.Catmethod=cry // 如果 cry 改为 hi 则会改变 Cat.class


package opp3;


public class Cat {private String name = "招财";public void hi(){System.out.println("hi,招财");}public void cry(){System.out.println("hi,喵喵叫");}}ReflectionQuestion.class


package opp3;


import javax.swing.plaf.synth.SynthOptionPaneUI;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Properties;


/**


  • 反射问题的引入*/public class ReflectionQuestion {

  • public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {//根据配置文件 re.properties 指定信息,创建 Cat 对象并调用 hi 方法


// Cat cat = new Cat();// cat.hi();


    //尝试做 明白反射
//1. 使用properties类,可以读写配置文件 Properties properties = new Properties(); properties.load(new FileInputStream("src\\re.properties")); String classfullpath = properties.get("classfullpath").toString(); String method = properties.get("method").toString(); System.out.println(classfullpath); System.out.println(method);
//2. 创建对象,传统的方法就要用 反射机制 System.out.println("=========================================="); //3. 使用反射机制解决 //(1)加载类,返回Class类型的对象 //(2)通过cls 得到加载的类 opp3.Cat 的对象实例 Class<?> cls = Class.forName(classfullpath);
Cat cat = (Cat) cls.newInstance(); System.out.println("运行类型"+cat.getClass()); //(3)通过 cls 得到你加载的类 opp3.Cat 的 hi 的方法对象 // 即:在反射中,可以把方法视为对象(万物皆对象) Method method1 = cls.getMethod(method); //通过method1 调用方法,即通过方法对象来实现调用方法 method1.invoke(cat); //反射机制 方法.invoke(对象) 传统:对象.方法
}
复制代码


}反射原理图 java.reflection


Java 反射插图


反射相关的主要类 java.lang.Class:代表一个类,Class 对象表示某个类加载后在堆中的对象 java.lang.reflect.Method:代表类的方法,Method 对象表示某个类的方法 java.lang.reflect.Field:代表类的成员变量,Field 对象表示某个类的成员变量 java.lang.reflect.Constructor:代表类的构造方法,Constructor 表示构造器这些类在 java.lang 包


package opp3;


public class Cat {private String name = "招财";public int age = 10;public Cat(){} //无参构造器 public Cat(String name){ this.name = name; }public void hi(){System.out.println("hi,招财");}public void cry(){System.out.println("hi,喵喵叫");}


public static class demo01 {}
复制代码


}classfullpath = opp3.Catmethod=crypackage opp3;


import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Properties;


public class demo01 {public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {


    Properties properties = new Properties();    properties.load(new FileInputStream("src\\re.properties"));    String classfullpath = properties.get("classfullpath").toString();    String method = properties.get("method").toString();
//2. 使用反射机制解决 //(1)加载类,返回Class类型的对象 Class<?> cls = Class.forName(classfullpath); //(2)通过cls 得到加载的类 opp3.Cat 的对象实例 Cat cat = (Cat) cls.newInstance(); System.out.println("运行类型"+cat.getClass()); //(3)通过 cls 得到你加载的类 opp3.Cat 的 hi 的方法对象 // 即:在反射中,可以把方法视为对象(万物皆对象) Method method1 = cls.getMethod(method); //通过method1 调用方法,即通过方法对象来实现调用方法 method1.invoke(cat); //反射机制 方法.invoke(对象) 传统:对象.方法
//java.lang.reflect.Field 代表类的成员变量,Field对象表示某个类的成员变量 //得到name //getField 不能得到private私有的属性
复制代码


// Field field = cls.getField("name"); //getField 不能得到 private 私有的属性 private String name = "招财";Field field = cls.getField("age");// 传统写法: 对象.成员变量 , 反射:成员变量对象.get(对象)System.out.println(field.get(cat)); // public int age = 10;


    //java.lang.reflect.Constructor 代表类的构造方法,Constructor表示构造器    Constructor<?> constructor = cls.getConstructor(); // () 中可以指定构造器参数类型 。括号里为空,则为无参构造器    System.out.println(constructor);    //public opp3.Cat()      public Cat(){}    //无参构造器
Constructor<?> constructor1 = cls.getConstructor(String.class);//这里传入的 String.class 就是String类的Class对象 System.out.println(constructor1); //public opp3.Cat(java.lang.String) public Cat(String name){ this.name = name; }
}
复制代码


}反射调用优化反射的


​ 优点:可以动态的创建和使用对象(也可以是框架底层核心),使用灵活,没有反射机制,框架即时就是去底层支撑


​ 缺点:使用反射基本就是解释执行,对执行速度有影响


package opp3;


import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;


public class demo02 {public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {m1();m2();


}
//传统方法public static void m1(){ Cat cat = new Cat(); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { cat.hi(); } long endTime = System.currentTimeMillis(); System.out.println("传统方法用时:" + (endTime-startTime));}
//反射机制public static void m2() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Class<?> cls = Class.forName("opp3.Cat"); Object o = cls.newInstance(); Method hi = cls.getMethod("hi"); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { hi.invoke(o); } long endTime = System.currentTimeMillis(); System.out.println("反射机制用时:" + (endTime-startTime));}
复制代码


}稍微优化一下 setAccessible(true);


setAccessible:启动和禁用访问安全检查的开关。参数值为 true 则指反射的对象在使用时应该取消 java 语言访问检查。


提高反射效率。如果代码中必须使用反射,而该句代码需要频发的被调用,那么请设置为 true 使得原本无法访问的私有成员也可以访问 package opp3;


import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;


public class demo02 {public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {m1();m2();m3();


}
//传统方法public static void m1(){ Cat cat = new Cat(); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { cat.hi(); } long endTime = System.currentTimeMillis(); System.out.println("传统方法用时:" + (endTime-startTime));}
//反射机制public static void m2() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Class<?> cls = Class.forName("opp3.Cat"); Object o = cls.newInstance(); Method hi = cls.getMethod("hi"); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { hi.invoke(o); } long endTime = System.currentTimeMillis(); System.out.println("反射机制用时:" + (endTime-startTime));}
//反射优化public static void m3() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Class<?> cls = Class.forName("opp3.Cat"); Object o = cls.newInstance(); Method hi = cls.getMethod("hi"); hi.setAccessible(true); //取消访问检查 long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { hi.invoke(o); } long endTime = System.currentTimeMillis(); System.out.println("反射机制用时:" + (endTime-startTime));}
复制代码


}Method 的 setAccessible 优化


Method hi = cls.getMethod("hi");hi.setAccessible(true);Field 的 setAccessible 优化


Field name = cls.getField("name");name.setAccessible(true);


//因为原来的的属性是 private,不能直接访问,所以需要关闭安全检测 private String name = "招财";Class 类 Class 也是类,因此也继承 Object 类 Class 类对象不是 new 出来的,而是系统生成的对于某个类的 Class 类对象,在内存中只有一份,因此类只加载一次每个类的实例都会记得自己是哪个 Class 实例所生成通过 Class 可以完整地得到一个类的完整结构,通过一些列 APIClass 对象是存放在堆中类的字节码二进制数据,是放在方法区,有的地方称为类的元数据(包括 方法代码,变量名,方法名,访问权限等等)Java 注解与反射 基础插图


获取 Class 对象的六种方法 package opp3;


/**


  • 演示 getClass()*/public class GetClass {public static void main(String[] args) throws ClassNotFoundException {

  • }}哪些类型有 Class 对象 class:外部类、成员(内部成员、外部成员),局部内部类,匿名内部类


interface:接口


[] :数组


enum:枚举


annotation:注解 @interface


primitive type:基本数据类型


void


package opp3;


import java.io.Serializable;


public class TypeClass {public static void main(String[] args) {Class stringClass = String.class; //外部类 Class serializableClass = Serializable.class; //接口 Class aClass = Integer[].class; //数组 Class aClass1 = float[][].class; //二维数组 Class deprecatedClass = Deprecated.class; //注解//枚举 Class stateClass = Thread.State.class;Class longClass = long.class; //基本数据类型 Class voidClass = void.class; //void 数据类型 Class classClass = Class.class;


   System.out.println(stateClass);   System.out.println(serializableClass);   System.out.println(aClass);   System.out.println(aClass1);   System.out.println(deprecatedClass);   System.out.println(serializableClass);   System.out.println(longClass);   System.out.println(voidClass);   System.out.println(classClass);
复制代码


}}类加载静态和动态加载静态加载:编译时加载相关类,如果没有则报错,依赖性太强动态加载:运行时加载需要的类,如果运行时不用该类,则不报错,降低依赖性类加载时机:


当创建对象时(new) //静态加载当子类被加载时,父类也加载 //静态加载调用类种的静态成员时 //静态加载通过反射 package opp3;


import java.lang.reflect.Method;


public class ClassLoad_ {public static void main(String[] args) throws Exception {// //静态加载,依赖性很强// //编译前必须有 Cat 类,否则会报错// Cat cat = new Cat();// cat.hi();


    //静态加载    //反射 -> 动态加载    //因为是动态加载,则就算编译前没有写有Cat类也没有报错。    //只有当动态加载到Cat类时,当发现没有Cat类时,才会报错    Class aClass = Class.forName("opp3.Cat");    Object o = aClass.newInstance();                         //新建一个对象o    Method hi = aClass.getMethod("hi");                hi.invoke(o);                  //激活新建对象o 的hi方法}
复制代码


}类加载流程图 Java 反射插图 2


Java 反射插图 3


类加载的五个阶段一、加载


二、验证阶段:


目的是为了去额宝 Class 文件的字节流种包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身安全包括:文件格式验证(是否以魔数 oxcafebabe 开头)、元数据验证、字节码验证和符号引用验证可以考虑使用 -Xverify:none 参数来关闭大部分的类验证措施,缩短虚拟机加载时间(只要你项目足够大,小项目就不考虑)三、准备阶段:


//1. n1 是实例属性,不是静态变量,因此在准备阶段不会分配内存//2. n2 是静态变量,分配内存 n2 是默认初始化 0 ,而不是 20//3. n3 是 static final 常量,它和静态变量不一样,因为一旦赋值就不边 n3 = 30


// class 内部//属性-成员变量-字段


public int n1 = 10;public static int n2 = 20;public static final int n3 = 30 四、解析 阶段


​ 虚拟机将常量池内的符号引用替换为直接引用的过程


五、初始化


到初始化阶段,才正在执行类中定义的 java 程序代码,此阶段是执行()方法的过程()方法是按语句在源文件中出现的顺序,依次自动收集类中所有的静态变量的赋值动作和静态代码块中的语句,并进行合并虚拟机会保证一个类()方法在多线程环境中被正确地加锁、同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的()方法,其他线程都需要阻塞等待,知道活动线程执行()方法完毕。反射获取类的结构信息第一组:


getName(); 获取全类名 getSimpleName(); 获取简单类名 getFields(); 获取所有 public 修饰的属性,包括父类的 getDeclaredFields(); 获取本类中所有属性 getMethods(); 获取多有的 public 修饰的方法,包括父类的 getDeclaredMethods(); 获取本类所有的方法 getConstructors(); 获取本类所有 public 修饰的构造器 getDeclaredConstructors(); 获取本类中所有的构造器 getPackage(); 以 package 形式返回父类信息 getSuperclass(); 以 class 形式返回父类信息 getInterfaces(); 以 Class[]形式返回接口信息 getAnnotations(); 以 Annotations[]形式返回注解信息 package opp3;


import org.testng.annotations.Test;


import java.lang.annotation.Annotation;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;


/**


  • 如何获取类的结构信息*/


public class Demo05 {public static void main(String[] args) throws Exception{api_01();}


@Testpublic static void  api_01() throws Exception {    /**     * 1. getName();   获取全类名     * 2. getSimpleName();    获取简单类名     * 3. getFields();   获取所有public修饰的属性,包括父类的     * 4. getDeclaredFields();     获取本类中所有属性     * 5. getMethods();      获取多有的public修饰的方法,包括父类的     * 6. getDeclaredMethods();    获取本类所有的方法     * 7. getConstructors();    获取本类所有public修饰的构造器,     * 8. getDeclaredConstructors();    获取本类中所有的构造器     * 9. getPackage();    以package形式返回父类信息     * 10. getSuperclass();    以class形式返回父类信息     * 11. getInterfaces();     以Class[]形式返回接口信息     * 12. getAnnotations();    以Annotations[]形式返回注解信息     */
Class cls = Class.forName("opp3.Person"); System.out.println(cls.getName());
System.out.println(cls.getSimpleName());
Field[] fields = cls.getFields(); for (Field field : fields) { System.out.println("本类及父类的属性" + field); }
Field[] declaredFields = cls.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println("本类的属性 " + declaredField); }
Method[] methods = cls.getMethods(); for (Method method : methods) { System.out.println("本类及父类method: " + method.getName()); }
Method[] declaredMethods = cls.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println("本类所有方法" + declaredMethod.getName()); }
Constructor[] constructors = cls.getConstructors(); for (Constructor constructor : constructors) { System.out.println("本类constructors: " + constructor); }
Constructor[] declaredConstructors = cls.getDeclaredConstructors(); for (Constructor declaredConstructor : declaredConstructors) { System.out.println("本类的declaredConstructors: " + declaredConstructor.getName()); //这里只是输出了名字 }
System.out.println(cls.getPackage());
System.out.println(cls.getSuperclass());
Class[] interfaces = cls.getInterfaces(); for (Class anInterface : interfaces) { System.out.println("接口信息:" + anInterface); }
Annotation[] annotations = cls.getAnnotations(); for (Annotation annotation : annotations) { System.out.println("注解信息" + annotation); }
}
复制代码


}


class A {public String hobby;public A(){}}


interface IA{


}interface IB{


}@Deprecatedclass Person extends A implements IA,IB{public String name;protected int age;String job;private double sal;


public void m1(){}
protected void m2(){}
void m3(){}
//构造器public Person(){}public Person(String name){}private Person(String name, int age){
}
复制代码


}第二组:java.lang.reflect.Field 类


getModifiers :以 int 形式返回修饰符


​ (说明:默认修饰符是 0 , public 是 1 , private 是 2, protected 是 4 ,static 是 8, final 是 16)


​ 其他的举例说明:修饰符 public static:1+8 = 9


getType:以 Class 形式返回类型


getName : 返回属性名


public void api_02() throws Exception{Class cls = Class.forName("opp3.Person");Field[] declaredFields = cls.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println("本类的所有属性 " + declaredField.getName()+" 该属性的修饰符值 " + declaredField.getModifiers()+ " 该属性的类型 " + declaredField.getType());}}第三组:java.lang.reflect.Method 类


getModifiers :以 int 形式返回修饰符


(说明:默认修饰符是 0 , public 是 1 , private 是 2, protected 是 4 ,static 是 8, final 是 16)


getReturnType: 以 Class 形式获取 返回类型


getName:返回方法名


getParameterTypes:以 Class[]返回参数类型数组


package opp3;


import org.testng.annotations.Test;


import java.lang.annotation.Annotation;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Type;


/**


  • 如何获取类的结构信息*/


public class Demo05 {public static void main(String[] args) throws Exception{api_01();}


@Testpublic void api_02() throws Exception{    Class cls = Class.forName("opp3.Person");    Field[] declaredFields = cls.getDeclaredFields();    for (Field declaredField : declaredFields) {        System.out.println("本类的所有属性 " + declaredField.getName()            +" 该属性的修饰符值 " + declaredField.getModifiers()            + "  该属性的类型 " + declaredField.getType());    }
Method[] declaredMethods = cls.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println("本类所有方法:" + declaredMethod.getName() +" 该方法的访问修饰符值:"+declaredMethod.getModifiers() +" 该方法的返回类型:" + declaredMethod.getReturnType() );
//输出当前这个方法的形参数组情况 Type[] genericParameterTypes = declaredMethod.getGenericParameterTypes(); for (Type genericParameterType : genericParameterTypes) { System.out.println("该方法的形参类型:" + genericParameterType); } }
}
复制代码


}


class A {public String hobby;public A(){}}


interface IA{


}interface IB{


}@Deprecatedclass Person extends A implements IA,IB{public String name;protected int age;protected static int id; //修饰符值 : 4 + 8 = 12String job;private double sal;


public void m1(String name,int age,double sal){}
protected String m2(){ return null;}
void m3(){}
//构造器public Person(){}public Person(String name){}private Person(String name, int age){
}
复制代码


}第四组:java.lang.reflect.Constructor 类


getModifiers :以 int 形式返回修饰符


(说明:默认修饰符是 0 , public 是 1 , private 是 2, protected 是 4 ,static 是 8, final 是 16)


getName:返回构造器名(全类名)


getParameterTypes:以 Class[]返回参数类型数组


package opp3;


import org.testng.annotations.Test;


import java.lang.annotation.Annotation;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Type;


/**


  • 如何获取类的结构信息*/


public class Demo05 {public static void main(String[] args) throws Exception{api_01();}


@Testpublic void api_02() throws Exception{    Class cls = Class.forName("opp3.Person");
Constructor[] declaredConstructors = cls.getDeclaredConstructors(); for (Constructor declaredConstructor : declaredConstructors) {
System.out.println("============================"); System.out.println("本类的declaredConstructors: " + declaredConstructor.getName()); //这里只是输出了名字
Class[] parameterTypes = declaredConstructor.getParameterTypes(); for (Class parameterType : parameterTypes) { System.out.println("该构造器的形参类型:" + parameterType); } }
}
复制代码


}


class A {public String hobby;public A(){}}


interface IA{


}interface IB{


}@Deprecatedclass Person extends A implements IA,IB{public String name;protected int age;protected static int id; //修饰符值 : 4 + 8 = 12String job;private double sal;


public void m1(String name,int age,double sal){}
protected String m2(){ return null;}
void m3(){}
//构造器public Person(){}public Person(String name){}private Person(String name, int age){
}
复制代码


}反射爆破创建实例方式一:调用类中的 public 修饰的无参构造器方式二:调用类中的指定构造器 Class 类相关方法 newInstance:调用类中的无参构造器,获取对应类的对象 getConstructor(Class...clazz):根据参数列表,获取对应的构造器对象 getDecalaredConstructor(Class...clazz):根据参数列表,获取对应的构造器对象 Constructor 类相关说法 setAccessible:爆破 newInstance(Object...obj):调用构造器 package opp3;


import java.lang.reflect.Constructor;


/**


  • 通过反射机制创建实例*/public class Demo06 {public static void main(String[] args) throws Exception {

  • }}


class User{private int age = 500;private String name = "Nahida";


public User(){    //无参构造器  public
}
private User(int age, String name) { //private的有参构造器 this.age = age; this.name = name;}
public User(String name){ //public的有参构造器 this.name = name;}@Overridepublic String toString() { return "User{" + "age=" + age + ", name='" + name + '\'' + '}';}
复制代码


}操作属性如何通过反射访问类中的成员


根据属性名获取 Field 对象


​ Field f = clazz 对象.getDeclaredField(属性名)


爆破:f.setAccessible(true) //f 是 Field


访问


f.set(o,值); //o 表示对象


syso(f.get(o)); // o 表示对象


如果是静态属性,则 set 和 get 中的参数 o,可以写成 null


package opp3;


import java.lang.reflect.Field;


/**


  • 反射操作属性*/public class Demo07 {public static void main(String[] args) throws Exception {//1.得到 Student 对应的 Class 对象 Class<?> aClass = Class.forName("opp3.Student");


// name.set(o,"巴巴托斯"); 也可以如下一句:name.set(null,"巴巴托斯"); //因为 name 是静态 static 的,所以 o 也可以是 null, 【注意】不是静态的的这么写会报错 System.out.println(o);System.out.println(name.get(o)); //获取属性值


}
复制代码


}


class Student{public int age; //公共 agepublic static String name;


public Student(){   //构造器
}
@Overridepublic String toString() { return "Student{" + "age=" + age + ",name=" + name + '}';}
复制代码


}操作方法如何通过反射访问类中的成员


访问方法:


根据方法名获取 Method 方法对象


​ Method f = clazz 对象.getDeclaredMethod(方法名, XX.class) //得到本类所有方法


获取对象:Object o = clazz.newInstance();


爆破:m.setAccessible(true); //m 是 Method


访问


Object returnValue = m.invoke(o,实参列表);


如果是静态属性,则 invoke 中的参数 o,可以写成 null


package opp3;


import java.lang.reflect.Method;


/**


  • 演示反射调用发发*/public class Demo08 {public static void main(String[] args) throws Exception {


// Method hi = aClass.getMethod("hi", String.class); //getMethod() 获取公共方法,这里可行,但是私有方法不行不能用//得到 hi 方法 Method hi1 = aClass.getDeclaredMethod("hi", String.class); //getDeclaredMethod() 获得类的所有方法,这里也可行 hi1.invoke(o,"香菱");


    //4. 调用私有方法    Method say = aClass.getDeclaredMethod("say", int.class, String.class, char.class);    say.setAccessible(true);    System.out.println(say.invoke(o,20,"云堇",'女'));    //因为say方法是静态的,还可以这么写: o 写成null    System.out.println(say.invoke(null,17,"胡桃",'女'));
//返回值: //5. 在反射中,如果方法有返回值,统一返回object,但是它运行类型和方法定义的返回类型一致 Object invoke = say.invoke(null, 16, "行秋", '男'); System.out.println("invoke的运行类型:" + invoke.getClass());
}
复制代码


}


class Boss{public int age;private static String name;


public Boss(){
}
private static String say(int n, String s , char c){ return n+ " " + s + " " + c;}
public void hi(String s){ System.out.println("hi " + s);}
复制代码


}作业 Java 反射插图 4


package opp3.opp32;


import java.lang.reflect.Field;import java.lang.reflect.Method;


public class HomeWork {public static void main(String[] args) throws Exception {//1. 得到 PrivateTest 类对应的 Class 对象 Class<?> cls = Class.forName("opp3.opp32.PrivateTest");


    //2. 创建对象实例    Object o = cls.newInstance();
//3. 得到name属性 Field name = cls.getDeclaredField("name");
//4. 爆破 name.setAccessible(true); name.set(o,"七七");
//5. 获得getName方法对象 Method getName = cls.getDeclaredMethod("getName");
//6. 因为getName是公有的,所以直接输出 Object invoke = getName.invoke(o); System.out.println("name的属性值:" + invoke );
}
复制代码


}


class PrivateTest{private String name = "HelloKitty";public String getName(){return name;}}Java 反射插图 5


package opp3.opp32;


import java.lang.reflect.Constructor;import java.lang.reflect.Method;


public class HomeWork02 {public static void main(String[] args) throws Exception {//1. 利用 Class 类的 forName 得到 File 类的 class 对象 Class<?> cls = Class.forName("java.io.File");//2. 获得所有的构造器 Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();//遍历输出所有的的构造器 for (Constructor<?> declaredConstructor : declaredConstructors) {System.out.println("File 的构造器:" + declaredConstructor);}//3. 单独的得到 public java.io.File(java.lang.String)Constructor<?> declaredConstructor = cls.getDeclaredConstructor(String.class);String filePath = "e://mynew.txt";Object file = declaredConstructor.newInstance(filePath); //创建文件 File 对象//4. 调用 createNewFile()方法,创建文件 Method createNewFile = cls.getDeclaredMethod("createNewFile");createNewFile.invoke(file);//file 的运行类型就是 FileSystem.out.println(file.getClass());System.out.println("文件创建成功");


}
复制代码


}

发布于: 刚刚阅读数: 3
用户头像

卢衍飞

关注

君子藏器于腹,待时而动. 2022-11-08 加入

宜塔阿里巴巴低代码高级开发师 腾讯云V加开发者认证 HarmonyOS应用开发者认证 华为云云享专家Java开发工程师

评论

发布
暂无评论
Java 反射_Java_卢衍飞_InfoQ写作社区