反射和泛型

一、反射

Java里面的反射可以帮助我们在运行程序时候加载、使用编译期间完全未知的class,简单来说就是Java可以加载一个运行时候才得知名称的class,获得其完整的构造,并生成实例化对象,对其成员变量赋值,调用其方法等等。

我的理解:反射就是将一个类的成员映射成相对应的类型,也包括该类本身

反射和类加载的区别

RTTI(Run Time Type Identification)即通过运行时类型识别,对RTTI来说,编译器会在编译期打开和检查.class文件。但对反射来说,.class文件是由运行时环境打开和检查。
请添加图片描述

反射关键类图

请添加图片描述

生成对象的步骤

请添加图片描述
1.正常new对象:

1.编译期加载.class文件

2.查找构造函数

3.通过构造函数创建对象

2.反射:

1.运行期加载.class文件

2.创建构造函数

3.通过构造函数创建对象

示例

1.Person类
public class Person {
   

    public String name = "com/xiaoMao";

    protected Integer age = 1;

    private Byte sex = (byte) 1;

    Boolean isMarriage = true;

    // 无参数
    public Person() {
   
    }

    // 有参数
    public Person(String name, Integer age, Byte sex, Boolean isMarriage) {
   
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.isMarriage = isMarriage;
    }

    public String getName() {
   
        return name;
    }

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

    public Integer getAge() {
   
        return age;
    }

    public void setAge(Integer age) {
   
        this.age = age;
    }

    public Byte getSex() {
   
        return sex;
    }

    public void setSex(Byte sex) {
   
        this.sex = sex;
    }

    public Boolean getMarriage() {
   
        return isMarriage;
    }

    public void setMarriage(Boolean marriage) {
   
        isMarriage = marriage;
    }

    private String privateMethod() {
   
        return "This is private method!";
    }

    @Override
    public String toString() {
   
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                ", isMarriage=" + isMarriage +
                '}';
    }
}
2.Test类
public class ReflectionTest {
   

    /**
     * 示例:创建Class对象的3种方式
     */
    @Test
    public void test() throws Throwable {
   
        // 方式一  类.class
        Class personClazz = Person.class;

        // 方式二  实例.getClass()
        Person person = new Person();
        Class personClazz1 = person.getClass();

        // 方式三  Class.forName("类的全路径")
        Class personClazz2 = Class.forName("com.xiaoMao.reflect.Person");

        System.out.println(personClazz == personClazz1);

        System.out.println(personClazz == personClazz2);

    }

    /**
     * 示例:通过Class创建实例对象
     * <p>
     * // 无参数
     * <bean id="person" class="com.xiaoMao.reflect.Person" />
     * <p>
     * // 有参数
     * <bean id="person" class="com.xiaoMao.reflect.Person" >
     * <constructor-arg index="0" type="java.lang.String" value="xiaoMao"/>
     * </bean>
     */
    @Test
    public void test2() throws Throwable {
   
        /** 首先:获得Person的字节码 */
        Class personClazz = Class.forName("com.xiaoMao.reflect.Person");

        /** 其次:通过Class对象,创建构造方法对象 */
        Constructor constructor1 = personClazz.getConstructor(); // 初始化无参构造方法
        Constructor constructor2 = personClazz.getConstructor(String.class, Integer.class, Byte.class,
                Boolean.class); // todo 初始化有参构造方法对象,注意这里获得有参构造方法是传参数类型不是传具体的参数值

        /** 最后:通过构造方法创建对象 */
        // 调用无参数构造方法创建Person对象
        Person person1 = (Person) constructor1.newInstance();
        person1.setName("xiaoMao1");
        System.out.println("person1=" + person1);

        // 调用有参数构造方法创建Person对象
        Person person2 = (Person) constructor2.newInstance("xiaoMao2", 10, (byte) 1, true);
        System.out.println("person2=" + person2);


        /** 补充内容:反射通过私有构造方法创建对象,破坏单例模式 */
        Class singletonPersonClazz = SingletonPerson.class;
        // getxxx 不能访问private属性(方法),会报异常,找不到该方法(这里是构造方法):java.lang.NoSuchMethodException
        // Constructor constructor3 = singletonPersonClazz.getConstructor();
        //想要访问私有(属性或方法)必须使用getDeclaredxxx方法,若想访问(改变)原来的值,必须在之后setAccessible(true)
        Constructor constructor3 = singletonPersonClazz.getDeclaredConstructor();
        constructor3.setAccessible(true);
        SingletonPerson singletonPerson = (SingletonPerson) constructor3.newInstance();
        SingletonPerson singletonPerson1 = SingletonPerson.getInstance();
        SingletonPerson singletonPerson2 = SingletonPerson.getInstance();
        System.out.println("singletonPerson==singletonPerson1 is " + (singletonPerson == singletonPerson1));
        System.out.println("singletonPerson==singletonPerson2 is " + (singletonPerson == singletonPerson2));
        System.out.println("singletonPerson1==singletonPerson2 is " + (singletonPerson1 == singletonPerson2));
    }

    /**
     * public属性的Field
     */
    @Test
    public void test3() throws Throwable {
   
        // 第一步:获得Class
        Class personClazz = Person.class;

        // 第二步:获得构造方法
        Constructor<
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值