创建型工厂设计模式之前置黑魔法(反射)

红烧土豆泥 等级 411 0 0

什么是反射? 为什么说反射是黑魔法? 为什么要在工厂设计模式前扯反射这东西? 首先,既然在工厂设计模式前整它,肯定是在处理工厂设计模式时会用到它;既然都用黑魔法来形容它了,肯定是它异常强大; 那什么是反射嘞?既然能被称为"反",那就肯定会有"正",那,正。。。是啥子嘞?想当然,既然平时我们都不怎么搞反射,那我们平日整的就是正了呗!平时我们实例化一个对象都是是使用new关键字,例如:

  Person per = new Person();

那反的自然就是不使用new关键字了嘛~ 在正式了解不使用new来实例化一个类前,我们需要先了解反射手下的几名大将(类)及它们的一些技能特效(方法使用)。


军师 -> Class类(java.lang.Class) 是不是突然眼前一亮,我好像在哪见过,好像还用过它,他不是关键字吗?怎么突然变成一个类了???是不是突然又突然发现经常用的那个class和这个Class还是有点区别的,没错,这个首字母大写了。那这个Class是干啥子的嘞? 首先让我们先看一个小demo

  public class Person {
    public Person() {}

    @Test
    public void fun() {
        Class<Person> clazz = Person.class;
        System.out.println(clazz);
        System.out.println(clazz.getName());
    }

}

输出的是:class test.reflect.Bean.Person test.reflect.Bean.Person 首先我们写了一个Person类,里面我们什么都没写,然后写了一个测试方法,通过Person.class获取了Class对象,输出后发现,就是此类的各级包路径+本类名。如果是clazz.getName则是没有了class这个头,也就是说它的Name值实际上就是test.reflect.Bean.Person。但是这个东东它有什么作用嘞?还不怎么清楚。继续再看,

  public class Person {
    public Person() {}

    @Test
    public void fun() {
        Person per = new Person();
        Class<? extends Person> clazz = per.getClass();
        System.out.println(clazz);
        System.out.println(clazz.getName());
    }
}

输出的是:class test.reflect.Bean.Person test.reflect.Bean.Person 我们在测试中,首先是将Person实例化了,然后通过getClass获取到了Class对象,输出的结果是不是发现他们竟然是一样子的,是不是突然感觉他们之间有着啥不可告人的秘密~ 再看下面的一个

  @Test
    public void fun() {
        try {
            Class<?> clazz = Class.forName("test.reflect.Bean.Person");
            System.out.println(clazz);
            System.out.println(clazz.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

输出的是:class test.reflect.Bean.Person test.reflect.Bean.Person 是不是想,噫 ~ 这东西有啥用哇?看出来了,看出来了,他们都是一样的,但是他们有啥子用嘛! 别急,别急,有没有注意到这边开始有异常抛出了,还是ClassNotFoundException异常,所以听我继续跟你们扯

  public class Person {
    private String name;

    public Person() {
    }

    public Person(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    public static void main(String[] args) {
        try {
            Class<?> clazz = Class.forName("test.reflect.Bean.Person");
            Person per = (Person) clazz.getDeclaredConstructor().newInstance();
            per.setName("老王");
            System.out.println(per.getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出:老王 在这个例子中,有没有注意到,没有new关键字的出现,感觉我没有对Person对象进行实例化,但是我却调用了它的getter和setter方法,还成功输出了"老王"。但是,既然输出了老王,那也就证明了Person这个对象被实例化了。怎么实例化的?没看到,偷麽麽的,那就是反的了呗!即通过反射对这个对象进行了实例化。 首先我们先看Class类的两个方法, 方法一:getDeclaredConstructor(类<?>... parameterTypes) -> 返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定 类函数。 方法二:newInstance() -> 创建由此 类对象表示的类的新实例。 看到这,你可能会想直接用newInstance()不就好了,为啥还要用上面的那个,如果你去翻看jdk的API的话你就会注意到这个方法在1.9版本就已经被废弃了,但是还可以使用,原文如下图 创建型工厂设计模式之前置黑魔法(反射) 文档上明确表述了它的作用Creates a new instance of the class represented by this Class object以及它的用法clazz.getDeclaredConstructor().newInstance(),到此,是不是可以联想到我们之前写的三个获取类的class对象的作用了。


来再看反射手下的第二名大将 大元帅 -> Method类(java.lang.reflect.Method) 我们先来看一段代码

  public class Person {
    private String name;

    public Person() {
    }

    public Person(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    public static void main(String[] args) {
        try {
            Class<?> clazz = Class.forName("test.reflect.Bean.Person");
            Method[] method = clazz.getDeclaredMethods();

            for(Method str:method) {
                System.out.println("方法名:"+str.getName()+"\t方法类型:"+Modifier.toString(str.getModifiers())+"\t返回值类型:"+str.getReturnType());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出: 方法名:getName 方法类型:public 返回值类型:class java.lang.String 方法名:main 方法类型:public static 返回值类型:void 方法名:setName 方法类型:public 返回值类型:void

是不是感觉输出这些东西很熟悉啊!但是你可能回想,这有啥用嘛! 别急,继续看下面的一个例子:

  public class Person {
    private String name;

    public Person() {
    }

    public Person(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    public static void main(String[] args) {
        try {
            Class<?> clazz = Class.forName("test.reflect.Bean.Person");
            Person per = (Person) clazz.getDeclaredConstructor().newInstance();
            Method[] method = clazz.getDeclaredMethods();

            for(Method str:method) {
                if("setName".equals(str.getName())) {
                    str.invoke(per, "老王");
                }
            }
            System.out.println(per.getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

看它的输出:老王 是不是感觉很神奇!到这可能还没搞清楚反射究竟是一个啥东西啊?扯了这么多,还没说明白!按照JAVA核心技术卷一的解释就是一个能分析类的能力的程序。 欲知后事如何,请看下篇黑魔法工厂的爱恨情仇 ~

收藏
评论区

相关推荐

Groovy初探
开始之前 了解本教程的主要内容,以及如何从中获得最大收获。 关于本教程 如果现在有人要开始完全重写 Java,那么 Groovy 就像是 Java 2.0。Groovy 并没有取代 Java,而是作为 Java 的补充,它提供了更简单、更灵活的语法,可以在运行时动态地进行类型检查。您可以使用 Groovy 随意编写 Java 应用程序,连接 Java
创建型工厂设计模式之前置黑魔法(反射)
什么是反射? 为什么说反射是黑魔法? 为什么要在工厂设计模式前扯反射这东西? 首先,既然在工厂设计模式前整它,肯定是在处理工厂设计模式时会用到它;既然都用黑魔法来形容它了,肯定是它异常强大; 那什么是反射嘞?既然能被称为"反",那就肯定会有"正",那,正。。。是啥子嘞?想当然,既然平时我们都不怎么搞反射,那我们平日整的就是正了呗!平时我们实例化一个对象都是是
java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一
java 泛型详解绝对是对泛型方法讲解最详细的,没有之一 对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下。 本文参考、、 1、概述泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。什么是泛型?
死磕Java泛型(一篇就够)
Java泛型,算是一个比较容易产生误解的知识点,因为Java的泛型基于擦除实现,在使用Java泛型时,往往会受到泛型实现机制的限制,如果不能深入全面的掌握泛型知识,就不能较好的驾驭使用泛型,同时在阅读开源项目时也会处处碰壁,这一篇就带大家全面深入的死磕Java泛型。 泛型擦除初探相信泛型大家都使用过,所以一些基础的知识点就不废话了,以免显得啰嗦。
java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'XXXXX' bean
mvc项目启动报这个错原因:rest/controller中映射的地址重复
Java枚举类妙用
上代码:java@Getterpublic enum NodeIdStatusRef { / reference / NI001_A001_AGREE(NodeIdEnum.NI001.getNodeId(), OrderStatus.A101.getCode(), OrderStatus.A101.getCo
第一天:今天学spring的时候遇到一个错误
具体错误如下:Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'testDao' is defined at org.springframework.beans.factory.support.D
Java泛型使用之实现一个能够对字符、整型、浮点型、字节型、对象进行大小比较的方法
定义一个泛型类,定义泛型T,存储咱们的最大值最小值,重载构造函数,存储最大最小值,重写toString方法; package person.xsc.practice;public class Num<T //定义最大最小值 public T max; public T min; public Num() //构造函数(有参) public Num(T
Java开发面试高频考点学习笔记(每日更新)
Java开发面试高频考点学习笔记(每日更新) 1.深拷贝和浅拷贝 2.接口和抽象类的区别 3.java的内存是怎么分配的 4.java中的泛型是什么?类型擦除是什么? 5.Java中的反射是什么 6.序列化与反序列化 7.Object有哪些方法? 8.JVM内存模型 9.类加载机制 10.对象的创建和对象的布局 11.Java的四种引用
阿里一线架构师技术图谱!十年开发经验Java架构师
开头我们面试的时候 ,经常会被问这种到问题:Spring中bean的循环依赖怎么解决? Spring中bean的加载过程? spring相关的问题一直是大厂面试常问到的一个问题,也是一直困扰这我们,不知道从哪里下手,今天举例分析大厂的一些spring相关的面试真题。和分享我学习spring相关问题所整理的一些知识点。 01 并发宝典:面试专题面试专题分为四个
面试官突击一问:深入理解mysql技术
京东Java研发岗一面(基础面,约1小时) 自我介绍,主要讲讲做了什么和擅长什么 springmvc和springboot区别 @Autowired的实现原理 Bean的默认作用范围是什么?其他的作用范围? 索引是什么概念有什么作用?MySQL里主要有哪些索引结构?哈希索引和B+树索引比较? Java线程池的原理?线程池有哪些?线程池
SpringBoot Validation参数校验 详解自定义注解规则和分组校验
前言Hibernate Validator 是 Bean Validation 的参考实现 。Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint在日常开发中,Hibernate Validator经常用来验证bean的字段,基于注解,方便快捷高效。在Spr
腾讯T3团队整理,持续更新中
Java基础1.JAVA 中的几种数据类型是什么,各自占用多少字节。2.String 类能被继承吗,为什么。3\. 两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗?4\. String 属于基础的数据类型吗?5.Java 中操作字符串都有哪些类?它们之间有什么区别?6.Java 中 IO 流分为几种?7.BIO、NIO
个人博客开发之blog-api项目统一结果集api封装
前言由于返回json api 格式接口,所以我们需要通过java bean封装一个统一数据返回格式,便于和前端约定交互, 状态码枚举ResultCodejavapackage cn.soboys.core.ret;import lombok.Getter;/ @author kenx @version 1.0 @date 2021/6/17 15:35
(转载)Java内存区域(运行时数据区域)和内存模型(JMM) - czwbig
转载自:Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数据分区域存储,强调对内存空间的划分。而内存模型(Java Memory Model,简称 JMM )是定义了线程和主内存之间的抽象关系,即 JMM 定义了 JVM 在计算机内存(RAM)中的工作方式,如果我们要想深入了解Java并发编程,就要先理解好Java内存模型。Java