Java反射原理与使用

当类加载器将类加载进jvm之后,jvm会创建每一个类的元数据对象(Class),这个元数据对象(Class)记录着这类的所有信息,java语言允许通过元数据对象动态的创建对象实例,这种机制就称为java的反射机制,基本上所有框架的底层都用到了反射机制,spring、mybatis、servlet都用到了

1.如何获取一个类的元数据对象(Class)呢

现在有一个User类

package com.niu.demo;

public class User {
    private String name;
    private String password;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

获取User的元数据对象(Class)方式

public class Main2 {
    public static void main(String[] args) {
        Class<User> aClass1 = User.class; // 1、类名.class
        Class<?> aClass2 = Class.forName("com.niu.demo.User"); //2、类完整的路径名
        User user = new User();
        Class<? extends User> aClass = user.getClass(); //3、对象引用.getClass()方式
    }
}

2.如何通过类的元数据对象(Class)创建对象呢

我们采用第一种获取Class对象的方式

Class<User> aClass1 = User.class; // 1、类名.class
User user = aClass1.newInstance();

这样就完成了通过反射的方式完成了类的创建

3.还可以对通过Class对象做什么

我们可以通过元数据Class对象获取对象的所有信息,如方法、属性、父类、接口、构造器。。。。

3.1 给属性赋值

public class Main2 {
    public static void main(String[] args) throws Exception {
        //1、第一种方式
        User user = new User();
        user.setName("张三");
        System.out.println(user.getName());
        //通过反射给属性赋值 传入属性名
        Field field = user.getClass().getDeclaredField("name");
        field.setAccessible(true);
        field.set(user,"李四");
        System.out.println(user.getName());
        
        //2、第二种方式
        User user1 = User.class.newInstance();
        user1.setName("王五");
        System.out.println(user1.getName());

    }
}

输出

3.2 反射调用对象方法

我们在User加入如下方法

    public boolean passwordCheck(String password){
        if (password==null || password.length()<3){
            System.out.println("password can't be used");
            return false;
        }else {
            System.out.println("password is ok");
            return true;
        }
    }

调用测试

    public static void main(String[] args) throws Exception {
        User user = new User();
        //传入方法名和参数类型
        Method passwordCheck = user.getClass().getDeclaredMethod("passwordCheck",String.class);
        Object invoke1 = passwordCheck.invoke(user, "12");
        System.out.println(invoke1);

        Object invoke2 = passwordCheck.invoke(user, "123");
        System.out.println(invoke2);
    }

输出

4、框架里是如何使用反射的

tomcat里web.xml

 <servlet>
  	<servlet-name>HelloServlet</servlet-name>
  	<servlet-class>servlet.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>HelloServlet</servlet-name>
  	<url-pattern>/servlet/HelloServlet</url-pattern>
  </servlet-mapping>

其中:<servlet-class>配置的完整类路径,然后通过Class.forName()来实例化servlet

spring的ioc  mybatis的mapper等等等等。。。 都是用到了反射

猜你喜欢

转载自blog.csdn.net/qq_41389354/article/details/111476884
今日推荐