java 日常学习记录-反射

Hero类

package helloworld;

public class Hero {
       public String name; //姓名
         
       public float hp; //血量
         
       public  float armor; //护甲
         
       public int moveSpeed; //移动速度
       
       public void setName(String name) {
           this.name=name;
           }
       
       public String getName() {
           return name;
    }
}

目的:读取Hero类属性 赋值,2:读取所有字段打印出类型和名称,3:调用方法

package helloworld;

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

//通过反射修改属性的值 测试类 Hero
//获取所有属性名称和类型
//调用方法

/*
     * //getField和getDeclaredField的区别
     * //getField 只能获取public的,包括从父类继承来的字段。
     * //getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。
 * */
public class TestReflection {
    public static void main(String[] argStrings) {
        //传统方式
        Hero hero=new Hero();
        hero.name="测试";
        
        try {
            //获取属性并设置值
            Field field = hero.getClass().getDeclaredField("name");
            //修改这个字段的值
            field.set(hero, "我是java学习的");
            //打印
            System.out.println(hero.name);
            
            //扩展获取所有字段
            Field[] fields = hero.getClass().getDeclaredFields();
            for(int i=0;i<fields.length; i++) {  
                Field  tempField = fields[i];
                //属性类型
                String typeNameString=tempField.getGenericType().toString();
                String name = tempField.getName();  
                System.out.println("字段名称:"+name+" 类型:"+typeNameString); 
            }
            
            //调用方法
            Method m=hero.getClass().getMethod("setName", String.class);
            m.invoke(hero, "第一个参数是具体调用的对象 第2个参数是赋值");
            // 使用传统的方式,调用getName方法
            System.out.println(hero.getName());
        }  catch (Exception e) {
            e.printStackTrace();
        }
    }
}

例子2:通过配置文件获取对象当配置文件里的内容发生变化的时候,就会得到不同的对象。 

源代码不需要发生任何变化,只需要修改配置文件,就可以导致程序的逻辑发生变化, 这是一种基于配置的编程思想。

spring 中的IOC和DI的底层就是基于这样的机制实现的(类似的Ling to Sql 也是通过类似的注解(类似net的类 字段上面加上特性) 加上反射 实现)

新建hero.config文件 内容:helloworld.APHero

package helloworld;

import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Constructor;
//需求:1:新建 hero.config 内容:helloworld.Hero
//2:通过反射读取hero.config 文件 取出其中的类名,根据类名实例化出对象
/*补充
 * 与传统的通过new 来获取对象的方式不同 
    反射机制,会先拿到Hero的“类对象”,然后通过类对象获取“构造器对象” 
    再通过构造器对象创建一个对象
    Spring框架中的IOC和DI的底层就是基于这样的机制实现的。
    获取类对象有3种方式
    1. Class.forName
    2. xxxx.class
    3. new xxxx().getClass()
*/
public class test {

    public static void main(String[] args) {
          Hero h = GetHero();
          System.out.println(h);
    }    
    
    public static Hero GetHero()   {
        try {
            //读取文件,测试学习不做异常(如 文件不存在)判断
            File f = new File("G:\\projectJava\\hero.config");
             FileReader fr = new FileReader(f);
             char[] all = new char[(int) f.length()];
             fr.read(all);
             fr.close();
             String className = String.valueOf(all);
            //反射 
            //得到类名
             className=new String(all).replaceAll("\\s*", ""); //helloworld.APHero helloworld.APHero
            //类对象
            Class<?> cs=Class.forName(className);
            //构造器 
            Constructor<?>  c=cs.getConstructor();        
            //通过构造器实例化
            Hero h= (Hero) c.newInstance();
            return h;
        } catch (Exception e) {
            return null;
        }    
    }
}

 

posted @ 2019-01-18 15:52  s_p  阅读(160)  评论(0编辑  收藏  举报