Java反射机制基本学习

1. 获取类的字节码

三种方式

  • 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包也不能省略
         */
         try{
            //第一种方式
            Class c1 = Class.forName("java.lang.String");
            //c1代表String.class文件,或者说c1代表String类型
         } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    
        //第二种方式
        //java中任何一个类都有一个getClass()方法
        Date d = new Date();
        Class class1 = d.getClass();
        
        //第三种方式,Java语言中任何一种类型,包括基本数据类型,它都有.class属性
        Class c = String.class;
    }
}

2. 通过Class的newInstance()方法来实例化对象

Class的newInstance()方法内部实际上调用了无参数构造方法,必须保证无参构造存在才可以。

public class ReflectTest02 {
    public static void main(String[] args) {
        // 这是不使用反射机制,创建对象
        User user = new User()
​
        // 下面这段代码是以反射机制的方式创建对象。
        try {
            // 通过反射机制,获取Class,通过Class来实例化对象
            Class c = Class.forName("com.bjpowernode.java.bean.User"); 
            // c代表User类型。
            // newInstance() 这个方法会调用User这个类的无参数构造方法,完成对象的创建。
            // 重点是:newInstance()调用的是无参构造,必须保证无参构造是存在的!
            Object obj = c.newInstance();
            System.out.println(obj); // com.bjpowernode.java.bean.User@10f87f48
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
}

3. Class.forName()这个方法的执行会导致:类加载。

希望一个类的静态代码块执行,其它代码一律不执行,可以使用:Class.forName("完整类名"); 这个方法的执行会导致类加载,类加载时,静态代码块执行。

4. 反射类当中的Field

public class ReflectTest03 {
    public static void main(String[] args) throws Exception{
        // 获取整个类
        Class studentClass = Class.forName("com.bjpowernode.java.bean.Student");
        //className = com.bjpowernode.java.bean.Student
        String className = studentClass.getName();
​
        //simpleName = Student
        String simpleName = studentClass.getSimpleName();
        
        // 获取类中所有的public修饰的Field
        Field[] fields = studentClass.getFields();
​
        // 获取所有的Field
        Field[] fs = studentClass.getDeclaredFields();
        // 遍历
        for(Field field : fs){
            // 获取属性的修饰符列表
            int i = field.getModifiers(); // 返回的修饰符是一个数字,每个数字是修饰符的代号!!!
            // 可以将这个“代号”数字转换成“字符串"
            String modifierString = Modifier.toString(i);
​
            // 获取属性的类型
            Class fieldType = field.getType();
            String fName = fieldType.getSimpleName();
            
            // 获取属性的名字
            field.getName();
        }
    }
}
public class Student {
    public int no;
    private String name;
    protected int age;
    boolean sex;
}

5. 反射类当中的Method

public class ReflectTest04 {
    public static void main(String[] args) throws Exception{
        // 获取类了
        Class userServiceClass = Class.forName("com.bjpowernode.java.service.UserService");
        // 获取所有的Method(包括私有的!)
        Method[] methods = userServiceClass.getDeclaredMethods();
        // 遍历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());
            }
        }
    }
}

6. 反射类当中的Constructor

public class ReflectTest05 {
    public static void main(String[] args) throws Exception{
        Class vipClass = Class.forName("java.lang.String");
        Constructor[] constructors = vipClass.getDeclaredConstructors();
        for(Constructor constructor : constructors){
            // 获取修饰符列表
            System.out.println(Modifier.toString(constructor.getModifiers()));
             // 获取构造方法名
            System.out.println(vipClass.getSimpleName());
            // 获取构造方法的形参类型
            Class[] parameterTypes = constructor.getParameterTypes();
            for(Class parameterType : parameterTypes){
                System.out.println(parameterType.getSimpleName());
            }
    }
}

7. 通过反射机制调用构造方法实例化java对象

public class ReflectTest06 {
    public static void main(String[] args) throws Exception{
        Class c = Class.forName("com.bjpowernode.java.bean.Vip");
        
        // 第一步:先获取到这个有参数的构造方法
        Constructor con = c.getDeclaredConstructor(int.class, String.class, String.class,boolean.class);
        // 第二步:调用构造方法new对象
        Object newObj = con.newInstance(110, "jackson", "1990-10-11", true);
        System.out.println(newObj);
​
        // 获取无参数构造方法
        Constructor con2 = c.getDeclaredConstructor();
        Object newObj2 = con2.newInstance();
        System.out.println(newObj2);
    }
}
​

8. 通过反射机制对对象属性赋值和获值

public class ReflectTest07 {
    public static void main(String[] args) throws Exception{
        Class studentClass = Class.forName("com.bjpowernode.java.bean.Student");
        // obj就是Student对象。(底层调用无参数构造方法)
        Object obj = studentClass.newInstance(); 
        
        // 获取no属性(根据属性的名称来获取Field)
        Field noFiled = studentClass.getDeclaredField("no");
​
        /*
        赋值三要素,缺一不可:
            要素1:对象
            要素2:属性
            要素3:值
            对象.属性 = 值;
         */
        noFiled.set(obj, 22222); // 给obj对象的no属性赋值2222
​
        // 读取属性的值
        // 两个要素:获取对象的属性的值。对象.属性;
        System.out.println(noFiled.get(obj));
​
        // 可以访问私有的属性
        Field nameField = studentClass.getDeclaredField("name");
        // 打破封装(反射机制的缺点:打破封装,可能会给不法分子留下机会!!!)
        // 这样设置完之后,在外部也是可以访问private的。
        nameField.setAccessible(true);
        // 给name属性赋值
        nameField.set(obj, "jackson");
        // 获取name属性的值
        System.out.println(nameField.get(obj));
    }
}
public class Student {
    public int no;
    private String name;
    protected int age;
    boolean sex;
}

9. 通过反射机制调用一个对象的方法

public class ReflectTest08 {
    public static void main(String[] args) throws Exception{
        /*
         调用方法要素分析:
            要素1:对象
            要素2:方法名
            要素3:实参列表
            要素4:返回值
            返回值 = 对象.方法名(实参列表);
         */
        Class userServiceClass = Class.forName("com.bjpowernode.java.service.UserService");
        // 创建对象
        Object obj = userServiceClass.newInstance();
        // 获取Method
        Method loginMethod = userServiceClass.getDeclaredMethod("login", String.class, String.class);
        //调用方法,得到返回值
        Object retValue = loginMethod.invoke(obj, "admin", "123123");
        System.out.println(retValue);
    }
}
public class UserService {
    public boolean login(String name,String passWord) {
        if("admin".equals(name) && "123".equals(passWord))
            return true;
        return false;
        
    }
}

10. 获取这个类的父类和实现了哪些接口

public class ReflectTest09 {
    public static void main(String[] args) throws Exception{
        // String举例
        Class stringClass = Class.forName("java.lang.String");
        
        // 获取String的父类
        Class superClass = stringClass.getSuperclass();
        System.out.println(superClass.getName());
        
        // 获取String类实现的所有接口(一个类可以实现多个接口。)
        Class[] interfaces = stringClass.getInterfaces();
        for(Class in : interfaces){
            System.out.println(in.getName());
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值