回顾反射机制

前言:反射机制在开发中很少使用,但是很多框架(Spring等)的实现原理是基于反射的,因此知道反射原理也很重要。

1.什么是反射机制?反射机制有什么作用?

反射机制:可以操作字节码文件。

作用:可以让程序更加灵活。

2.反射机制相关的类在哪个包下?

java.lang.reflect .*

3.反射机制相关的主要类:

java.lang.Class;

java.lang.reflect.Method;

java.lang.reflect.Constructor;

java.lang.reflect.Field;

4.在java中获取Class的三种方式

Class c = Class.forName(完整类名);

Class c = 对象.getClass();

Class c = int.class;

5.获取Class后可以调用无参数构造方法实例化对象:

Class c = Class.forName("java.util.Date");

Object obj = c.newInstance();//调用的是该类型的无参构造方法,如果没有这个无参构造方法会出现异常

6:如果只想要一个类的静态代码块执行:

Class.forName()

7:获取路径下的文件

(1):获取文件的绝对路径,该文件要求放在类路径下:也就是src下面.通用路径,不受环境影响。

String path = Thread.currentThread().getContextCalssLoader().getResource("类路径").getPath();

(2):直接以流的形式返回

InputStream reader = Thread.currentThread().getContextClassLoader().getResourceAsStream("classinfo.properties");

(3):资源绑定器:文件必须是类路径下的XXX.properties

ResourceBundle bundle = ResourceBundle.getBundle("classinfo");//文件名不加properties
String className1 = bundle.getString("className");

8:获得类中的所有属性Field

        Class studentClass = Class.forName("Student");
        //获取类中所有的field
        Field[] fields = studentClass.getFields();
        Field f = fields[0];
        String name =  f.getName();
        System.out.printf(name);
        Field[] fieldss = studentClass.getDeclaredFields();
        for(Field fs :fieldss){
            System.out.printf(fs.getName());}

9:通过反射机制,反编译一个类的属性Field

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class ReflectTest02 {
    public static void main(String[] args) throws Exception {
        Class studentClass = Class.forName("Student");
        StringBuilder s = new StringBuilder();
        Field[] fs = studentClass.getDeclaredFields();
        s.append(Modifier.toString(studentClass.getModifiers())+" "+"class"+" "+studentClass.getSimpleName()+"{\n");//动态获取修饰符和类名
        for(Field fd :fs){
            s.append("\t");
            s.append(Modifier.toString(fd.getModifiers()));
            s.append(" ");
            s.append(fd.getType().getSimpleName());
            s.append(" ");
            s.append(fd.getName());
            s.append(";\n");
        }
        s.append("}");
        System.out.println(s);
    }
}

10:通过反射机制访问对象属性:具有通用性,修改配置文件即可,尽管复杂,但是灵活性强。(重要!!!)

import java.lang.reflect.Field;

public class ReflectTest03 {
    /*
    怎么通过反射机制访问java对象的属性?
    (1)给属性赋值 set
    (2)获取属性的值 get

     */
    public static void main(String[] args) throws Exception{
        //首先获取整个class
        Class studentClass = Class.forName("Student");
        //实例化对象
        Object obj = studentClass.newInstance();
        //要给属性赋值,首先要获得这个属性,依靠名字来区分
        Field no = studentClass.getDeclaredField("no");
        //obj对象(Student对象)的no属性赋值
        no.set(obj,2222);
        System.out.println(no.get(obj));

    }
}

11:通过反射机制访问私有变量,打破了封装,是反射的一个缺点


        Field nameField = studentClass.getDeclaredField("name");
        nameField.setAccessible(true);
        nameField.set(obj,"lucy");
        System.out.println(nameField.get(obj));

12:反射Method

补充:可变长度参数:int... args【类型后跟3个点】,在参数列表中必须是最后一个,而且只能出现一个。可以被看做一个数组

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ReflectTest04 {
    public static void main(String[] args) throws Exception {
        //获得类
        Class studentClass = Class.forName("Student");
        //获得所有的method,包括私有的
        Method[] methods = studentClass.getDeclaredMethods();
        //遍历methods
        for(Method method :methods){
            //获得修饰符列表
            System.out.println(Modifier.toString(method.getModifiers()));

            //获得方法得返回值类型
            System.out.println(method.getReturnType().getSimpleName());

            //获得方法得修饰符列表,一个方法得参数可能会有多个
            Class[] parameters = method.getParameterTypes();
            for(Class parameter:parameters){
                System.out.println(parameter.getSimpleName());
            }
        }
    }
}

13:通过反射机制调用方法执行(重要!!!)

import java.lang.reflect.Method;

public class ReflectTest05 {
    public static void main(String[] args) throws Exception{
        //获取类名
        Class studentClass = Class.forName("Student");
        //创建对象
        Object obj = studentClass.newInstance();
        //获取方法,方法名和参数列表
        Method testMethod = studentClass.getDeclaredMethod("add",int.class,int.class);
        // 调用方法,对象、方法名、实际参数列表、返回值
       Object value =  testMethod.invoke(obj,2,3);
        System.out.println(value);

    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值