java反射

反射机制

反射机制有什么用?

通过java语言中的反射机制可以操作字节码文件(可以读和修改字节码文件)。通过反射机制可以操作代码片段(class文件)

反射机制的相关类在哪个包下?
java.lang.reflect.*;

反射机制相关的重要类有哪些?
java.lang.Class:代表整个字节码,代表一个类型。代表整个类
java.lang.reflect.Method:代表字节码中的方法字节码。代表类中的方法
java.lang.reflect.Field:代表字节码中的属性字节码。代表类中的构造方法
java.lang.reflect.Constructor:代表字节码中的构造方法字节码。代表类中的成员变量(静态变量+实例变量)

三种方式获取java.lang.Class实例:

package com.bjpowernode.java.reflect;

import java.util.Date;

/*
要操作一个类的字节码,首先需要获取到这个类的字节码,怎么获取java.lang.Class实例?
有三种方式
    第一种:Class c = Class.forName("完整类名带包名")
    第二种:Class c = 对象.getClass();
    第三种:Class c = 任何类型.class;
 */
public class ReflectTest01 {
    public static void main(String[] args) {
        /*
        一、Class.forName()
        1.静态方法
        2.方法的参数是一个字符串
        3.字符串需要的是一个完整类名
        4.完整类名必须带有包名。java.lang包也不能省略
         */
        Class c1 = null;
        Class c2 = null;
        try {
            c1 = Class.forName("java.lang.String");
            c2 = Class.forName("java.util.Date");
            Class c3 = Class.forName("java.lang.Integer");
            Class c4 = Class.forName("java.lang.System");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //二、java中任何一个对象都有一个方法:getClass()
        String s = "abc";
        Class x = s.getClass();
        System.out.println(c1 == x);//true,==判断的是对象的内存地址

        Date time = new Date();
        Class y = time.getClass();
        System.out.println(c2 == y);//c2和y两个变量中保存的内容地址都是一样的,都指向方法区中的字节码文件

        //三、java语言中任何一种类型,包括基本数据类型,它都有.class属性
        Class z = String.class;//z代表String类型
        Class k = Date.class;//k代表Date类型
        Class f = int.class;//f代表int类型
        Class e = double.class;//e代表double类型

        System.out.println(x==z);//true


    }
}

7eqZgx.png

package com.bjpowernode.java.bean;

public class User {
    public User(){
        System.out.println("我是无参构造");
    }
    public User(String s){
        System.out.println("有参构造");
    }
}

package com.bjpowernode.java.reflect;

import com.bjpowernode.java.bean.User;

/*
获取到Class,能干什么?
通过Class的newInstance()方法来实例化对象
注意:newInstance()方法内部实际上调用了无参构造方法,必须保证无参构造存在才可以。
 */
public class ReflectTest02 {
    public static void main(String[] args) {
        //这是不使用反射机制,创建对象
        User user = new User();
        System.out.println(user);

        //下面是使用反射机制创建对象
        try {
            //通过反射机制,获取Class,通过Class来实例化对象
            Class c = Class.forName("com.bjpowernode.java.bean.User");

            //newInstance()这个方法会调用User这个类的无参数构造方法,完成对象的创建、
            //重点是:newInstance()调用的是无参构造,必须保证无参构造是存在的!
            Object obj = c.newInstance();
            System.out.println(obj);
            }catch (InstantiationException e) {
                e.printStackTrace();
            }catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            catch(ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}

package com.bjpowernode.java.reflect;

import com.bjpowernode.java.bean.User;

import java.io.FileReader;
import java.util.Properties;
/*
验证反射机制的灵活性
    java代码写一遍,在不改变java源码的基础之上,可以做到不同对象的实例化。
    非常之灵活。(符合OCP开闭原则:对扩展开放,对修改关闭。)
 */
public class ReflectTest03 {
    public static void main(String[] args) throws Exception {
        //这种方式就写死了,只能创建一个User类型的对象
        User user = new User();

        //以下代码是灵活的,代码不需要改动,可以修改配置文件,配置文件修改之后,可以创建出不同的实例对象。
        //通过IO流读取classinfo.properties文件
        FileReader reader = new FileReader("D:\\IdeaProjects\\bjpowernodejavase\\chapter25\\classinfo.properties");
        //创建属性类对象Map
        Properties pro = new Properties();
        //加载
        pro.load(reader);
        //关闭流
        reader.close();
        //通过key获取value
        String className = pro.getProperty("className");
        System.out.println(className);

        //通过反射机制实例化对象
        Class c = Class.forName(className);
        Object obj = c.newInstance();
        System.out.println(obj);


    }
}

Class.forName()发生了什么?
如果你只是希望一个类的静态代码块执行,其他代码一律不执行,
你可以使用:
Class.forName(“完整类名”)
这个方法的执行会导致类加载,类加载时,静态代码块执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值