反射机制

**反射机制的作用:**通过反射机制来访问class文件的java对象的属性,方法,构造方法等
获取字节码文件常用的三种方法:
第一种:Class c1 = Class.forName(“java.lang.String”);
完整包名+类名 静态方法方法参数是一个字符串字符串需要时一个完成的类名 完整的类名必须带有包名
第二种:Class c2 = 对象.getClass();
第三种方式 java中任何一种类型,都有相对应的class属性。Class z = String.class; Class m = Date.class;Class e = int .class;
如何获取类的绝对路径?在任何系统上都是通用路径,前提文件时在src根目录下

String path = Thread.currentThread().getContextClassLoader()
        .getResource("classinfo.properties").getPath();

获取了Class文件我们能做什么?
1.通过Class的newInstance()实例化对象,并且调用了无参构造方法
2.Class. forName()方法执行,进行了类加载,静态代码块执行
3.通过io流读取classinfo.properties文件,或许key和value,然后通过反射机制,实例化对象进行。
classinfo.properties文件

className=Reflect.User
public class ReflcetTest03 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
        //通过io流读取classinfo.properties文件
        FileReader reader = new FileReader("D:\\JDEA\\untitled1\\src\\classinfo.properties");
        //创建属性类对象 key value 都是String类型的
        Properties pro = new Properties();
        //加载
        pro.load(reader);
        //关闭流
        reader.close();
        //通过key获取value
        String className = pro.getProperty("className");
        //通过反射机制实例化对象,实例化的是Usr类
        Class c = Class.forName(className);
        Object obj = c.newInstance();
        System.out.println(obj);
    }
}
class User{
    public User() {
        System.out.println("无参构造执行");
    }
}

获取字段/属性的类型int,String,double等/修饰符列public static final/名字

 public static void main(String[] args) throws Exception {
        //获取整个类
        Class studentClass = Class.forName("Reflect.Student");

        String s1 = studentClass.getName();//返回完整类名
        System.out.println(s1);
        String s2 = studentClass.getSimpleName();//返回简单类名
        System.out.println(s2);
        //获取类中所有Filed方法,但是只能获取public修饰的
        Field[] fields = studentClass.getFields();
        System.out.println(fields.length);//测试数组中只有一个元素
        //取出这个数组中Field字段/属性
        Field f = fields[0];
        //取出Field的名字
        String s = f.getName();
        System.out.println(s);

        System.out.println("-------------");

        //获取所有的Field
        Field[] field = studentClass.getDeclaredFields();
        System.out.println(field.length);//数组中有4个元素
        for (Field ff : field){
            //获取属性修饰符列表
            //修饰符可能有多个 public static final  ff.getModifiers();
            int i = ff.getModifiers();
            //返回值是数字,将数字转换成字符串
            String modifier = Modifier.toString(i);
            System.out.println(modifier);

            //获取属性类型
            //变量.获取类型.获取类型的名字
            String fName = ff.getType().getName();//也可以获取简单名字
            System.out.println(fName);

            //获取属性名字
            System.out.println(ff.getName());
        }

    }
}
//反射属性
class Student{
    //Field翻译为字段, 其实就是属性/成员
    //4个Field分别采用了不同的访问控制权限修饰符
    public int no ;//整个是一个Field对象
    private String name;
    protected int age;
    boolean sex;
    public static final double PI = 3.1415;

    public Student() {
    }

    public Student(int no, String name, int age, boolean sex) {
        this.no = no;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
}

反射Method方法

public class ReflcetTest11 {

    public static void main(String[] args) throws ClassNotFoundException {
        //获取类
        Class user = Class.forName("Reflect.UserService");
        //获取所有Method(包括私有)
        Method[] methods = user.getDeclaredMethods();
        //System.out.println(methods.length);//2

        //遍历Method
        for (Method method : methods){
            //获取修饰符列表
            System.out.println(Modifier.toString(method.getModifiers()));
            //或许返回值类型
            System.out.println(method.getReturnType().getSimpleName());
            //获取方法名
            System.out.println(method.getName());
            //方法的修饰符列表(一个方法的参数可能会有多个)需要遍历
            Class[] ParameterTypes = method.getParameterTypes();
            for (Class ParameterType : ParameterTypes){
                System.out.println(ParameterType.getSimpleName());
            }

        }
    }
}
/*
 *功能描述
 * @author 肥蛋
 * @date
 * @param  name 用户名
 * @param  password 密码
 * @return true表示成功 false表示失败
 */
class UserService{
    public boolean login(String name,String password){
        if ("admin".equals(name) && "123".equals(password)){
            return true;
        }return false;
    }
    public void logout(){
        System.out.println("系统安全退出");
    }
}

总结:想获取类里的什么就获取类然后调用getDeclared-----相应的构造方法
getDeclaredConstructors();获取构造方法,返回Constructor数组
getDeclaredMethods();获取方法,返回Method数组
getDeclaredFields();获取字段/属性,返回Field数组
怎么利用反射机制调用构造方法?

public class ReflectTest15 {
    public static void main(String[] args) throws Exception {
        Class Vip = Class.forName("Reflect.Vip");
        //调用无参数构造方法
        Object obj = Vip.newInstance();
        //获取构造方法
        Constructor c1 = Vip.getDeclaredConstructor(int.class,String.class,String.class,boolean.class);
        Constructor c2 = Vip.getDeclaredConstructor(int.class,String.class);
        //调用构造方法
        Object c1Obj = c1.newInstance(111,"java","1990",true);
        System.out.println(c1Obj);

        Object c2Obj = c2.newInstance(111,"java");
        System.out.println(c2Obj);

    }
    class Vip{
    int no;
    String name;
    String birth;
    boolean sex;

    public Vip() {
    }

    public Vip(int no) {
        this.no = no;
    }

    public Vip(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public Vip(int no, String name, String birth) {
        this.no = no;
        this.name = name;
        this.birth = birth;
    }

    public Vip(int no, String name, String birth, boolean sex) {
        this.no = no;
        this.name = name;
        this.birth = birth;
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Vip{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", birth='" + birth + '\'' +
                ", sex=" + sex +
                '}';
    }
}

}

怎么通过反射机制调用方法?

public class ReflectTest13 {
    public static void main(String[] args) throws Exception {
        Class UserService = Class.forName("Reflect.UserService");

        //创建对象,调用无参数构造方法
        Object obj = UserService.newInstance();
        Method loginMethod = UserService.getDeclaredMethod("login", String.class,String.class);
        //loginMethod是方法  obj是对象  "admin","123"是传入参数  retValue是返回值
        Object retValue = loginMethod.invoke(obj, "admin","123");
        System.out.println(retValue);
    }
}
class UserService{
    public boolean login(String name,String password){
        if ("admin".equals(name) && "123".equals(password)){
            return true;
        }return false;
    }
    public void logout(){
        System.out.println("系统安全退出");
    }
}

怎么通过反射机制访问一个java属性?
给属性赋值set
获取属性值get

public static void main(String[] args) throws Exception{
    //使用反射机制,给对象赋值
    Class stuClass = Class.forName("Reflect.Student");
    //调用无参数构造方法,获取对象obj
    Object obj = stuClass.newInstance();

    //获取no属性(根据属性名称来获取Field)
    Field nofield = stuClass.getDeclaredField("no");
    //赋值set 取值get
    nofield.set(obj, 111);
    System.out.println(nofield.get(obj));

    //可以访问私有变量嘛?
    Field nameFiled = stuClass.getDeclaredField("name");

    //打破封装(缺点:安全性太差)
    //这样设置之后外部也是可以访问private的
    nameFiled.setAccessible(true);
    //给name属性赋值
    nameFiled.set(obj, "jack");
    System.out.println(nameFiled.get(obj));
}
class Student{
    //Field翻译为字段, 其实就是属性/成员
    //4个Field分别采用了不同的访问控制权限修饰符
    public int no ;//整个是一个Field对象
    private String name;
    protected int age;
    boolean sex;
    public static final double PI = 3.1415;

    public Student() {
    }

    public Student(int no, String name, int age, boolean sex) {
        this.no = no;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
}

怎么获取类实现接口和父类?

/*获取类实现接口和父类*/
public class ReflectTest16 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class c = Class.forName("java.lang.String");

        //类的父类
        Class superclass = c.getSuperclass();
        System.out.println(superclass);

        //实现接口
        Class[] interfaceClass = c.getInterfaces();
        for (Class interfacer : interfaceClass){
            System.out.println(interfacer.getName());
        }

    }
}

资源绑定器
便于获取配置文件中的内容。使用以下这个方式的时候,属性配置文件xxx.properties必须放刀类路径下。、
文件内容className=Reflect.User

public class ResourceBundleTest01 {
    public static void main(String[] args) {

        //资源绑定器,只能绑定xxx.properties,并且文件在类路径下。文件扩展名只能是properties
        //并且在写路径的时候,路径后边的扩展名不能写
        ResourceBundle bundle = ResourceBundle.getBundle("classinfo");
        String className = bundle.getString("className");
        System.out.println(className);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值