精华内容
下载资源
问答
  • NULL 博文链接:https://zouwu85.iteye.com/blog/801921
  • java反射与泛型

    2021-03-10 08:01:42
    反射与泛型相关的接口和类1 Typejava中所有类型的公共实现接口,实现该接口的有原始类型,参数化类型,数组类型,类型变量和基本类型。2 GenericDeclaration声明类型变量的所有实体的公共接口`TypeVariable>[] ...

    反射中与泛型相关的接口和类

    1 Type

    java中所有类型的公共实现接口,实现该接口的有原始类型,参数化类型,数组类型,类型变量和基本类型。

    2 GenericDeclaration

    声明类型变量的所有实体的公共接口`TypeVariable>[] getTypeParameters();`返回泛型声明中的类型变量 如Map中返回的是键值K,V

    3 ParameterizedType 参数化类型Type[] getActualTypeArguments();

    Type getRawType(); 原始类型 ,如Class的实例类Class的RawType是Class

    Type getOwnerType(); 泛型类是内部类

    泛型与反射

    Java中的泛型是一种伪泛型,会在编译期间被擦出,所以无法在运行时获得有关泛型的信息。

    但是在某些情况下,可以在运行期获得泛型的信息。

    下面是两个典型的使用泛型的场景:

    1 声明一个需要被参数化(parameterizable)的类或者接口

    2 使用一个参数化的类

    当你声明一个类或者接口的时候你可以指明这个类或接口可以被参数化, java.util.List 接口就是典型的例子。你可以运用泛型机制创建一个标明存储的是String类型List,这样比你创建一个Object的List要更好。

    你不能在运行期获知一个被参数化的类型的具体参数类型是什么,但是你可以在用到这个被参数化类型的方法以及变量中找到他们,换句话说就是获知他们具体的参数化类型。

    泛型方法返回类型

    获得了java.lang.reflect.Method对象,那么就可以获取到这个方法的泛型返回类型信息。

    如果方法是在一个被参数化类型之中(如 T fun())那么你无法获取他的具体类型,但是如果方法返回一个泛型类(译者注:如 List fun())那么你就可以获得这个泛型类的具体参数化类型。)class MyClass {

    private List stringList = new ArrayList();

    public List getStringList() {

    return this.stringList;

    }

    }

    我们可以获取 getStringList()方法的泛型返回类型,换句话说,我们可以检测到 getStringList()方法返回的是 List 而不仅仅只是一个 List。Method method = MyClass.class.getMethod("getStringList",null);

    Type returnType = method.getGenericReturnType();

    if(returnType instanceof ParameterizedType) {

    ParameterizedType type = (ParameterizedType)returnType;

    Type[] typeArguments = type.getActualTypeArguments();

    for(Type typeArgument : typeArguments) {

    Class typeArgClass = (Class) typeArgument;

    System.out.println("typeArgClass = " + typeArgClass);

    }

    }

    输出:typeArgClass = class java.lang.String

    Class类实现了Type接口,这里通过反射获得了参数类型的信息。

    泛型方法参数类型

    可以通过反射来获取方法参数的泛型类型。method = MyClass.class.getMethod("setStringList", List.class);

    Type[] genericParameterTypes = method.getGenericParameterTypes();

    for(Type genericParameterType : genericParameterTypes){

    if(genericParameterType instanceof ParameterizedType){

    ParameterizedType aType = (ParameterizedType) genericParameterType;

    Type[] parameterArgTypes = aType.getActualTypeArguments();

    for(Type parameterArgType : parameterArgTypes){

    Class parameterArgClass = (Class) parameterArgType;

    System.out.println("parameterArgClass = " + parameterArgClass);

    }

    }

    }

    输出:parameterArgClass = class java.lang.String

    泛型变量类型

    通过反射可以访问公有(public)变量的泛型类型。无论是一个类的静态成员变量还是实例成员变量,都可以获取到。Field field = MyClass.class.getField("stringList");

    Type genericFieldType = field.getGenericType();

    if(genericFieldType instanceof ParameterizedType){

    ParameterizedType aType = (ParameterizedType) genericFieldType;

    Type[] fieldArgTypes = aType.getActualTypeArguments();

    for(Type fieldArgType : fieldArgTypes){

    Class fieldArgClass = (Class) fieldArgType;

    System.out.println("fieldArgClass = " + fieldArgClass);

    }

    }

    输出:fieldArgClass = class java.lang.String

    补充:在集合中使用参数化类型,这样禁止我们在编译期间插入与类型不符合的参数,但是通过反射,由于反射是在运行期发生作用,且java中的泛型在编译期间就会被擦除了,因此可以跳过编译期间的检查,插入任意类型的数据。public class GenericEssence {

    public static void main(String[] args) {

    List list1 = new ArrayList(); // 没有泛型

    List list2 = new ArrayList(); // 有泛型

    /*

    * 1.首先观察正常添加元素方式,在编译器检查泛型,

    * 这个时候如果list2添加int类型会报错

    */

    list2.add("hello");

    // list2.add(20); // 报错!list2有泛型限制,只能添加String,添加int报错

    System.out.println("list2的长度是:" + list2.size()); // 此时list2长度为1

    /*

    * 2.然后通过反射添加元素方式,在运行期动态加载类,首先得到list1和list2

    * 的类类型相同,然后再通过方法反射绕过编译器来调用add方法,看能否插入int

    * 型的元素

    */

    Class c1 = list1.getClass();

    Class c2 = list2.getClass();

    System.out.println(c1 == c2); // 结果:true,说明类类型完全相同

    // 验证:我们可以通过方法的反射来给list2添加元素,这样可以绕过编译检查

    try {

    Method m = c2.getMethod("add", Object.class); // 通过方法反射得到add方法

    m.invoke(list2, 20); // 给list2添加一个int型的,上面显示在编译器是会报错的

    System.out.println("list2的长度是:" + list2.size()); // 结果:2,说明list2长度增加了,并没有泛型检查

    } catch (Exception e) {

    e.printStackTrace();

    }

    /*

    * 综上可以看出,在编译器的时候,泛型会限制集合内元素类型保持一致,但是编译器结束进入

    * 运行期以后,泛型就不再起作用了,即使是不同类型的元素也可以插入集合。

    */

    }

    }

    展开全文
  • Java反射与泛型

    2021-12-29 17:13:27
    1、Java反射:在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。 2、Java泛型:JDK5以后引入的一个新...

    1、Java的反射:在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。

    2、Java泛型:JDK5以后引入的一个新特性。是指类型参数化。允许在定义类、接口、方法时使用类型形参,当使用时指定具体类型。

    泛型类、泛型方法、泛型类派生的子类、类型通配符

    泛型的上限:上界<? extends T> 不能往里存,只能取。

    泛型的下限:下界<? super T> 可以存,取的时候只能返回Object对象。

    类型擦除与桥接方法:(可通过反射的方法 看到实际的接口返回等等)

    擦除:为了向下兼容(jdk1.5以前的版本) ,当java文件被加载成class文件时不带有泛型的信息。

    桥接:由于类型被擦除了 编辑器会自动生成桥接方法。

    展开全文
  • 主要介绍了JAVA 反射泛型的的相关资料,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
  • 可以使用Java泛型,如下: public class Factory { private T pk; public Factory(){} public Factory(T pk){ this.pk=pk; } } Factory创建实例的时候,确实是通过构造函数将id传给成员变量id了,但是创建的是...

    现有几个类,构造函数的参数都是一样的,就是创建的实例对象不一样。具体如下:

    class StringFunction{
        String id;
        public StringFunction(){}
        public StringFunction(String id){
            this.id=id;
            System.out.println("创建了StringFunction实例");
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    }
    
    class IntegerFunction{
        Integer id;
        public IntegerFunction(Integer id){
            this.id=id;
            System.out.println("创建了IntegerFunction实例");
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    }
    
    class LongFunction{
        Long id;
        public LongFunction(Long id){
            this.id=id;
            System.out.println("创建了IntegerFunction实例");
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public Long getId() {
            return id;
        }
    }

    现在,想要根据传进来的参数创建实例对象,发现上面几个类的带参构造函数都是传一个id,然后将这个id赋给成员变量id,这时候我就想能不能有一个创建一个公共的类,通过构造函数创建实例对象,也是将值赋给成员变量id。可以使用Java的泛型,如下:

    public class Factory<T> {
    
        private T pk;
    
        public Factory(){}
    
        public Factory(T pk){
            this.pk=pk;
        }
    }

    Factory创建实例的时候,确实是通过构造函数将id传给成员变量id了,但是创建的是Factory实例对象,我就是想要一个StringFunction类的实例对象,怎么办?

    这个时候反射就体现他的作用了。

    能否编写一个根据传过来的 类   参数数组 创建对应的实例变量的方法呢?这就要用到Java的范式和反射,代码如下:

    public class Factory<T> {
    
        public T getObject(Class<? extends T> myClass, Object[] parameters) throws Exception {
    
            //创建参数类型数组
            Class[] parametersType = new Class[parameters.length];
    
            //获取各参数类型
            for (int i = 0; i < parameters.length; i++) {
                Class<?> aClass = parameters[i].getClass();
                parametersType[i] = aClass;
            }
    
            //根据参数类型获取相应的构造函数
            Constructor<? extends T> constructor = myClass.getConstructor(parametersType);
    
            //返回实例对象
            return constructor.newInstance(parameters);
        }
    }

    调用:

    class Test {
        public static void main(String[] args) throws Exception {
            Object[] param = {"myPK"};
            Factory<StringFunction> factory = new Factory<StringFunction>();
            StringFunction stringFunction = factory.getObject(StringFunction.class, param);
        }
    }

     结果如下:

    通过反射获取某个类的实例对象,构造函数的参数也可以根据需要变化,个人觉得复用性很强,为了方便就简写一个类,想要开发项目的,建议写成接口。

    展开全文
  • Java反射泛型、容器

    2021-03-22 17:04:50
    反射一、什么是反射?Class是反射的核心。JVM中每个Class实例都指向一个数据类型(class或者interface),而这个实例又包含有class的所有信息。二、创建Class对象的三种方式JVM创建的class 的实例Class具有唯一性。创建...

    反射

    一、什么是反射?

    Class是反射的核心。

    JVM中每个Class实例都指向一个数据类型(class或者interface),而这个实例又包含有class的所有信息。

    二、创建Class对象的三种方式

    JVM创建的class 的实例Class具有唯一性。

    创建一个实体类Person:

    package com.company.demo2;

    public class Person {

    public String name;

    private Integer age;

    public Person() {

    }

    public Person(String name, Integer age) {

    this.name = name;

    this.age = age;

    }

    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;

    }

    }

    方法一:直接通过一个class的静态变量class获取

    // 方式一:类.class

    Class personClazz = Person.class;

    方法二:通过该实例变量提供的getClass()方法获取

    // 方式二:示例.getClass()

    Person person = new Person();

    Class personClazz1 = person.getClass();

    方法三:通过静态方法Class.forName()获取

    // 方式三:Class.forName("类的全路径")

    Class personClazz2 = Class.forName("com.company.demo2.Person");

    拓展

    因为Class实例在JVM中是唯一的,所以,上述方法获取的Class实例是同一个实例。可以用==比较两个Class实例:

    Class cls1 = String.class;

    String s = "Hello";

    Class cls2 = s.getClass();

    boolean sameClass = cls1 == cls2; // true

    注意一下Class实例比较和instanceof的差别:

    Integer n = new Integer(123);

    boolean b1 = n instanceof Integer; // true,因为n是Integer类型

    boolean b2 = n instanceof Number; // true,因为n是Number类型的子类

    boolean b3 = n.getClass() == Integer.class; // true,因为n.getClass()返回Integer.class

    boolean b4 = n.getClass() == Number.class; // false,因为Integer.class!=Number.class

    用instanceof不但匹配指定类型,还匹配指定类型的子类。而用双等于判断class实例可以精确地判断数据类型,但不能作子类型比较。

    通常情况下,我们应该用instanceof判断数据类型,因为面向抽象编程的时候,我们不关心具体的子类型。只有在需要精确判断一个类型是不是某个个class的时候,我们才使用双等于判断class实例。

    三、通过Class创建对象

    不考虑反射,正常场景:

    Person person = new Person(); // 调用构造方法

    考虑反射,同样也是需要靠构造方法来创建对象的。

    无参构造方法

    public void test2() throws Exception {

    //第一步:获取到Class对象

    Class personClazz = Person.class;

    // 第二步:获取构造方法

    Constructor constructor = personClazz.getConstructor();

    // 第三步:创建对象

    Person person = constructor.newInstance();

    System.out.println(person);

    }

    Spring组件即通过反射使用无参构造方法创建bean:

    有参构造方法

    public void test3() throws Exception {

    // 第一步:获取到Class对象

    Class personClazz = Person.class;

    // 第二步:获取构造方法

    Constructor constructor = personClazz.getConstructor(String.class, Integer.class);

    // 第三步:创建对象

    Person person = constructor.newInstance("张三", 10);

    System.out.println(person);

    System.out.println(person.getName() + ":" + person.getAge());

    }

    Spring组件即通过反射使用有参构造方法创建bean:

    四、通过反射获取属性值

    反射是指将一个类的成员映射成相对应的java类型。

    成员:

    属性Field.java

    方法(构造函数Constructor.java、静态方法、普通方法Method.java)

    包路径 Package.java

    public void test4() throws Exception {

    // 第一步:获取Class对象

    Class personClazz = Person.class;

    // 第二步:获取构造方法

    Constructor constructor = personClazz.getConstructor(String.class, Integer.class);

    Person person = constructor.newInstance("张三", 10);

    // 第三步:通过Class对象,获取Field对象

    // a.获取public权限的属性

    Field nameField = personClazz.getField("name");

    // b.获取private权限的属性

    Field ageField = personClazz.getDeclaredField("age");

    ageField.setAccessible(true);

    // 第四步:获取属性值

    String name = String.valueOf(nameField.get(person));

    int age = (Integer) ageField.get(person);

    System.out.println(name + ":" + age);

    }

    五、创建一个反射工具类

    public static void convertOf(Object sourceObj, Object targetObj) throws Exception {

    Class sourceClass = sourceObj.getClass();

    Class targetClass = targetObj.getClass();

    Field[] sourceClassDeclaredFields = sourceClass.getDeclaredFields();

    Field[] targetClassDeclaredFields = targetClass.getDeclaredFields();

    for (Field sourceClassDeclaredField : sourceClassDeclaredFields) {

    for (Field targetClassDeclaredField : targetClassDeclaredFields) {

    sourceClassDeclaredField.setAccessible(true);

    targetClassDeclaredField.setAccessible(true);

    if (sourceClassDeclaredField.getName().equals(targetClassDeclaredField.getName())) {

    targetClassDeclaredField.set(targetObj, sourceClassDeclaredField.get(sourceObj));

    }

    }

    }

    }

    public static void main(String[] args) throws Exception {

    //属性值复制

    Person person = new Person("aaa", 12);

    Person1 person1 = new Person1();

    Main.convertOf(person, person1);

    System.out.println(person1.getName() + ":" + person1.getAge1());

    }

    补充:

    package com.company.demo2;

    public class Person1 {

    public String name;

    private Integer age1;

    public Person1() {

    }

    public Person1(String name, Integer age1) {

    this.name = name;

    this.age1 = age1;

    }

    public String getName() {

    return name;

    }

    public void setName(String name) {

    this.name = name;

    }

    public Integer getAge1() {

    return age1;

    }

    public void setAge1(Integer age1) {

    this.age1 = age1;

    }

    }

    泛型

    容器

    本文地址:https://blog.csdn.net/qq_33507618/article/details/111992595

    希望与广大网友互动??

    点此进行留言吧!

    展开全文
  • Java反射 - 泛型

    2021-03-04 01:49:55
    使用Java泛型通常分为两种不同的情况:声明一个类/接口是可参数化的。使用可参数化的类。当你写一个类或接口时,你可以指定它应该是可参数化的。 java.util.List接口就是这种情况。 而不是创建一个Object列表,你可以...
  • 前言关于Java泛型,很多人都有一个误解,认为Java代码在编译时会擦除...泛型的使用场景在讨论如何用反射获取泛型类型之前,我们先来回顾下,在Java里面什么时候会使用泛型,了解这个问题之后,我们才能继续思考如何...
  • Java反射获取泛型类型

    2021-02-12 11:45:06
    public class Person{}importjava.lang.reflect.ParameterizedType;importjava.lang.reflect.Type;public class Student extends Person{public static voidmain(String[] args) {Student st=newStudent();Class cla...
  • java泛型反射机制

    2018-09-13 15:12:02
    java泛型以及反射机制进行原理和应用上的讲解,帮助初学者对这两个概念进行更轻松的掌握
  • Java反射泛型----你真的不知道哟!

    千次阅读 2019-05-29 23:45:16
    Java反射泛型----带你通向光明顶 目录 1. Java反射---基础巩固 1.1Class概述 1.2Field概述 1.3Method概述 1.4 Constructor概述 2. 注解(Annotation) 2.1 Annotation概述 2.2 使用元注解 2.3 自定义...
  • 本课程是《 java就业班》系统课程的第24章,全套课程精细讲解,该课程超过其他机构30%的课程量,经过我们全套课程系统学习的同学,可轻松从事Java高级工程师或系统架构师岗位,课程提供全套代码笔记其它相关素材及...
  • 主要介绍了Java使用反射来获取泛型信息,结合实例形式分析了java基于反射操作泛型信息的相关实现技巧注意事项,需要的朋友可以参考下
  • Java反射操作泛型接口

    千次阅读 2018-02-23 17:16:10
    通过反射获取到抽象类或者接口中泛型信息的操作也是很常见的。实际上开发中,解析后台数据的Json数据,生成对应的泛型实体类,会用到反射获取泛型信息的操作。 实战案例 大致思路: getGenericInterfaces()获取...
  • 通过指定对应的Class对象,程序可以获得该类里面所有的Field,不管该Field使用private 方法public。...但此方法只对普通Field有效,若该Field有泛型修饰,则不能准确得到该Field的泛型参数,如Map<Strin...
  • java泛型与反射总结

    2020-02-29 18:30:38
    泛型基础 类型变量的限定 例如我们有一个泛型方法min,其中的形参是也是一个泛型数组。我们要使用泛型变量smallest的comparTo方法,就要求类型变量T是可以实现Comparable接口的类。 为了解决这种问题,我们可以使用...
  • 1.泛型反射API用来生成在当前JAVA虚拟机中的类、接口或者对象的信息。Class类:反射的核心类,可以获取类的属性,方法等内容信息。Field类:Java.lang.reflect.表示类的属性,可以获取和设置类的中属性值。Method类:...
  • 一:反射获取泛型信息 泛型的参数信息: package Reflection; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import ...
  • 利用java反射调用泛型的方法

    千次阅读 2019-10-23 20:36:23
    java反射比较耗资源、效率不高 创建一个通用于pojo的工具类Service,Service中用到了泛型T,并且需要调用T(pojo)中的方法,解决方案示例如下: Service.java import java.lang.reflect.Method; public class ...
  • java 反射操作泛型

    2021-02-28 06:09:19
    java 反射操作泛型public class emm {public void test01(Mapmap,Listlist){System.out.println("test01");}public Map test02(){System.out.println("test02");return null;}public static void main(String[] args...
  • 通常泛型在如下几种情况下使用: 含有泛型的类 // 格式 修饰符 class 类名<代表泛型的变量> { } // 实例 public class ArrayList<E> { public boolean add(E e){ } public E get(int index){ } } ...
  • Java 通过反射获取泛型的类型

    千次阅读 2019-08-06 21:39:56
    由于 Java泛型在运行时会被擦除,不能够直接获取泛型的类型,但是其实在 class 字节码中还是保存着泛型的信息,可以通过特殊的方式获取到泛型的类型 获取父类中的泛型类型 /** * 定义一个抽象的父类 * 获取...
  • Java Reflect综述Class类的使用方法的反射成员变量的反射构造函数的反射类加载机制Class 类的使用在面向对象的世界里,万事万物皆对象。但在Java里面有两样东西不是对象:静态的成员、普通数据类型类(但它们有封装类...
  • java中用反射获取泛型信息的方法发布时间:2020-06-22 09:51:08来源:亿速云阅读:143作者:Leah这篇文章给大家分享的是java中用反射获取泛型信息的方法,相信大部分人都还没学会这个技能,为了让大家学会,给大家...
  • Java 泛型的参数只可以代表类,不能代表个别对象。由于 Java 泛型的类型参数之实际类型在编译时会被消除,所以无法在运行时得知其类型参数的类型。package com.zhiming.tree;import java.lang.reflect.Method;import...
  • java反射获得泛型参数

    2018-07-25 16:14:57
    public class Person&...import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class Student extends Person&lt;Student&gt; { public static void main(String[]...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 61,343
精华内容 24,537
关键字:

java反射与泛型

java 订阅