Java 之反射

             共有方法       获取成员变量      获取构造方法        获取成员方法        获取全类名             配置文件案列

1.java代码在计算机中经历的阶段:

    1.源码  xxx.java文件           2.javac编译为字节码文件 ,包含一些成员方法,属性,构造方法,类名信息等

    3.使用类加载器往内存中加载,包含成员变量,构造方法,成员方法 都存在一个数组中      4.new的时候 运行阶段

 2.将类的各个组成部分封装为其他对象,这就是反射机制
      1. 可以在程序运行过程中,操作这些对象。    2. 可以解耦,提高程序的可扩展性。

 3.反射的三种方式

     1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
            * 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
     2. 类名.class:通过类名的属性class获取
            * 多用于参数的传递
     3. 对象.getClass():getClass()方法在Object类中定义着。
            * 多用于对象的获取字节码的方式
   注意:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。

 共有方法

  1.getName()  获得str类型名字         2.  setAccessible(true):暴力反射    设置private成员 或调用时需要设置

    public class Person {
    public int age;
    public String name;
    String name2;
    private int cm;
    @Override
    public String toString() {
    }
    public void eat(){
        System.out.println("eat..");
    }
    public void eat(String str){
        System.out.println("eat: "+str);
    }
    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }
    public Person() {
    }
}

获取成员变量

    * Field[] getFields() :                      获取所有public修饰的成员变量  返回一个数组
    * Field getField(String name)           获取指定名称的 public修饰的成员变量

     * Field[] getDeclaredFields()           获取所有的成员变量,不考虑修饰符包括private的
     * Field getDeclaredField(String name)  
        1. 设置值  * void set(对象名), Object value)     2. 获取值* get(对象名) 

        Person person = new Person();
        Class personClass = Person.class;
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
            System.out.println(field);  public int 反射.day01.Person.age  public java.lang.String 反射.day01.Person.name
        }
        Field names = personClass.getField("name");
        names.set(person,"wyc");

        Field cm = personClass.getDeclaredField("cm");   可以获取私有的
        cm.setAccessible(true);      获取或者设置私有成员变量 需要为true
        Object o = cm.get(person);
        System.out.println(o);   0
        cm.set(person,15);
        System.out.println(person); Person{age=0, name='wyc', cm=15}

获取构造方法

      * Constructor<?>[ ] getConstructors()      获取所有public修饰的构造方法返回一个数组
      * Constructor<T> getConstructor(类<?>... parameterTypes)     获取指定名称的 public修饰的构造方法

      * Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)  获取所有的构造方法,不考虑修饰符包括private的
      * Constructor<?>[] getDeclaredConstructors()             newInstance(构造参数)   用来创建对象

public static void main(String[] args) throws Exception {
Person person = new Person();
Class personClass = Person.class;
Constructor[] constructors = personClass.getConstructors();
for (Constructor constructor : constructors) {
    System.out.println(constructor);   }    打印所有构造方法                                                                 
                                                      获取有参的构造方法
Constructor constructor = personClass.getConstructor(int.class, String.class);
System.out.println(constructor);    public 反射.day01.Person(int,java.lang.String)
Object wyc = constructor.newInstance(15, "wyc");   用来创建对象
System.out.println(wyc);    Person{age=15, name='wyc', cm=0}}

获取成员方法

     * Method[] getMethods()  
     * Method getMethod(String name, 类<?>... parameterTypes)  

     * Method[] getDeclaredMethods()  
    * Method getDeclaredMethod(String name, 类<?>... parameterTypes)      invoke(对象名),方法参数)      常用的  用来调用方法

        public static void main(String[] args) throws Exception {
        Person person = new Person();
        Class personClass = Person.class;
        Method[] methods = personClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);     也会打印父类的,
        }
        Method eat = personClass.getMethod("eat");  无参数eat
        eat.invoke(person);
        Method eat1 = personClass.getMethod("eat", String.class);  参数是String.class
        eat1.invoke(person, "屎");          有参数
    }  如果调用私有 set

获取全类名  

   * String getName()

        Person person = new Person();
        Class personClass = Person.class;
        System.out.println(personClass.getName());   打印全称 :反射.day01.Person
    }

配置文件案列

   1.通过反射获取配置文件中的配置  达到不改变该类的任何代码前提下创建任意类的对象,可以执行任意方法

  1..创建一个配置文件promy.Properties    写入要创建的 类 名 ,  该类中要执行的方法

className=reflect.day01.Person     必须写全 不然报错
methodName=eat
public static void main(String[] args) throws Exception {
        创建与IO流有关的 集合用来 加载配置文件
        Properties properties = new Properties();

        获取类加载器
        ClassLoader classLoader = ReflectTestmy.class.getClassLoader();

        使用类加器获取配置文件输入流
        InputStream is = classLoader.getResourceAsStream("promy.Properties");

        使用properties集合 传入配置文件输入流 加载该配置文件
        properties.load(is);

        通过properties集合  用键获取值
        String className=properties.getProperty("className");
        String methodName=properties.getProperty("methodName");

        使用反射 加载该类进入内存
        Class cls = Class.forName(className);

        创建该类的对象
        Object obj = cls.newInstance();

        获取该类的方法
        Method eat = cls.getMethod("eat", String.class);
        eat.invoke(obj,"屎");   调用方法
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值