首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

带你深挖Java泛型类型擦除以及类型擦除带来的问题

1.Java泛型的实现方法:类型擦除 大家都知道,Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除。...Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。...原始类型 就是擦除去了泛型信息,最后在字节码中的类型变量的真正类型,无论何时定义一个泛型,相应的原始类型都会被自动提供,类型变量擦除,并使用其限定类型(无限定的变量用Object)替换。...不是说泛型变量String会在编译的时候变为Object类型吗?为什么不能存别的类型呢?既然类型擦除了,如何保证我们只能使用泛型变量限定的类型呢?...Pair,在子类中,我们覆盖了父类的两个方法,我们的原意是这样的:将父类的泛型类型限定为Date,那么父类里面的两个方法的参数都为Date类型。

1.7K40

带你深挖Java泛型类型擦除以及类型擦除带来的问题

1.Java泛型的实现方法:类型擦除 大家都知道,Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除。...Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。...原始类型 就是擦除去了泛型信息,最后在字节码中的类型变量的真正类型,无论何时定义一个泛型,相应的原始类型都会被自动提供,类型变量擦除,并使用其限定类型(无限定的变量用Object)替换。...不是说泛型变量String会在编译的时候变为Object类型吗?为什么不能存别的类型呢?既然类型擦除了,如何保证我们只能使用泛型变量限定的类型呢?...Pair,在子类中,我们覆盖了父类的两个方法,我们的原意是这样的:将父类的泛型类型限定为Date,那么父类里面的两个方法的参数都为Date类型。

3.9K21
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【说站】java泛型中类型擦除的转换

    java泛型中类型擦除的转换 说明 1、泛型值存在于编译阶段,当代码进入虚拟机时,泛型值将被删除。 2、这个特征被称为类型删除。当泛型被删除时,他有两种转换方法。...第一种是,如果泛型没有设置类型上限,泛型将转换为Object类型,第二种是如果设置了类型上限,泛型将转换为其类型上限。...getT() {         return t;     }     public void setT(T t) {         this.t = t;     } } //通过反射调用获取他们的属性类型...Field field : aClass.getDeclaredFields()) {         System.out.println("Test1属性:" + field.getName() + "的类型为...:" + field.getType().getName());     } } 以上就是java泛型中类型擦除转换的方法,希望对大家有所帮助。

    1.2K20

    泛型擦除是什么意思_泛型类和泛型方法的区别

    大家好,又见面了,我是你们的朋友全栈君 在严格的泛型代码里,带泛型声明的类总应该带着类型参数。但为了与老的Java代码保持一致,也允许在使用带泛型声明的类时不指定实际的类型。...如果没有为这个泛型类指定实际的类型,此时被称作raw type(原始类型),默认是声明该泛型形参时指定的第一个上限类型。...当把一个具有泛型信息的对象赋给另一个没有泛型信息的变量时,所有在尖括号之间的类型信息都将被扔掉。...比如一个 List 类型被转换为List,则该List对集合元素的类型检查变成了泛型参数的上限(即Object)。...上述规则即为泛型擦除,可以通过下面代码进一步理解泛型擦除: List list1 = ...; List list2 = list1; // list2将元素当做Object处理 从逻辑上来看

    1.3K30

    【说站】Java泛型擦除的原理分析

    Java泛型擦除的原理分析 1、说明 在编译过程中,可以获得类型变量的信息。因此,set方法可以在编译器中进行类型检查,非法类型不能通过编译。...但是对于get方法,由于擦除机制,操作时的实际引用类型是Object类型。 为了恢复返回结果的类型,编译器在get后添加了类型转换。...因此,在genericHolder.class文件main方法主体的第18行有类型转换的逻辑。这是编译器自动添加的。 因此,我们处理了泛型对象的读写位置,并对代码添加了限制。...                  // class java/lang/String       21: astore_2             22: return         } 以上就是Java泛型擦除的原理分析

    30330

    java反射技术的案例之泛型擦除

    泛型擦除 正确理解泛型概念的首要前提是理解类型擦除(type erasure)。 Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节代码中是不包含泛型中的类型信息的。...使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉。这个过程就称为类型擦除。如在代码中定义的List和List等类型,在编译之后都会变成List。...类型擦除也是Java的泛型实现方式与C++模板机制实现方式之间的重要区别。 很多泛型的奇怪特性都与这个类型擦除的存在有关,包括: 泛型类并没有自己独有的Class类对象。...因为异常处理是由JVM在运行时刻来进行的。由于类型信息被擦除,JVM是无法区分两个异常类型MyException和MyException的。...* 我来告诉大家,其实程序编译后产生的.class文件中是没有泛型约束的,这种现象我们称为 * 泛型的擦除。

    1.2K10

    Java基础知识:泛型的类型擦除、逆变与协变

    public static void main(String[] args) { List stringList = new ArrayList(); } } **思考:**泛型类型被擦除是否可以通过反射机制来继续获取泛型类型的信息...ArrayList 对象,而不是 String 类型的 ArrayList 因而该泛型类型被擦除。...总结:泛型类型擦除 ≈ 没有擦除,无论是局部变量中传入的泛型还是类定义上携带的泛型,只要传入了泛型,那么在生成的字节码文件中必然会额外记录这些泛型的具体信息。...对于不同的对象可以通过不同的反射机制来进一步获取被擦除的泛型类型: (一) 对于挂载在类上的泛型信息,可以通过来获取泛型信: IntList.class.getGenericSuperclass();...code 部分的指令,将 code 中的泛型信息去除掉了 ==> 即所谓的泛型擦除。

    78030

    【Flutter】Dart 泛型 ( 泛型类 | 泛型方法 | 特定类型约束的泛型 )

    接口 , 方法 提供复用性 , 支持类型不确定的数据类型 ; 泛型类 : 提高代码复用程度 ; 泛型方法 : 参数或返回值有泛型类型约束 , 参数或返回值类型必须符合对应的泛型类型 , 泛型使用时会进行类型检查约束..., 泛型类型设置为 int 类型 Cache cache2 = Cache(); // 调用泛型方法时 , 传入的参数必须符合对应的泛型类型 // 泛型约束 : 泛型使用时会进行类型检查约束...Tom I/flutter (24673): 泛型测试, 类型整型, 获取的缓存内容为 18 二、Dart 泛型中的特定类型约束 ---- 泛型还可以进行特定类型约束 , 如指定该泛型类型必须是某个类的子类..._person); /// 获取 _person 的名字 String getName(){ return _person.name; } } 上述涉及到的两个类在 【Flutter...int _grade; String school; String city; String address; /// 父类构造函数调用 : 如果父类有非空参数的构造函数, 子类必须实现相同参数的构造函数

    5.4K00

    关于Java泛型擦除的一点思考

    说到泛型,就不得说起“擦除”这个概念,相比于c#来说,java的泛型只存在于程序的源码中,在编译后的class文件中不存在,这个过程就是--泛型"擦除";所以,对于new ArrayList 和 new ArrayList 来说,两个对象在编译之后两者是一样的,通过反射均可以向集合中添加任意类型的对象; ?...直到学习了jackson后,我发现java泛型的“擦除”并不能一概而论;至少通过TypeReference接口,是可以获取到对象中的泛型; ?...按照之前所说,由于泛型“擦除”的原因,泛型在编译后的class文件中就不存在了,只会保留原始类型(Type中的概念),那么TypeReference又是如何实现,获取到了具体的泛型类型呢!...由此,对于java泛型的“擦除”并不能一概而论,在运行期间,如果方法中出现带泛型的匿名内部类,那么泛型依旧会被保留下来,我们可以通过对应的方法获取到实际的泛型类型!

    1.5K50

    深入探索C++17的std::any:类型擦除与泛型编程的利器

    它通过类型擦除的方式,隐藏了存储对象的具体类型信息,使得我们可以在不关心具体类型的情况下进行数据的存储和传递。构建方式构造函数直接赋值最直观的初始化方式就是通过构造函数直接赋值。...std::make_anystd::make_any是一个函数模板,它以更显式的方式指定初始化的类型,并通过完美转发来构造对象。这不仅提高了代码的可读性,还在某些情况下具有更好的性能。..."true" : "false") 类型擦除实现在模块化编程中,不同模块之间可能需要传递数据,但某些模块可能不关心数据的具体类型。...使用std::any可以隐藏数据的具体类型信息,实现类型擦除。例如,一个日志模块可能只需要记录数据,而不需要知道数据的具体类型。...总结std::any为C++开发者提供了强大的类型擦除和泛型编程能力,使得在处理不同类型数据时更加灵活和安全。

    7410

    泛型类、泛型方法、类型通配符的使用

    泛型类、泛型方法、类型通配符的使用 一.泛型类        泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分...和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。...下面是定义泛型方法的规则: 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前(在下面例子中的)。...每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。...类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。 泛型方法体的声明和其他方法一样。

    3.8K40

    一句话,讲清楚java泛型的本质(非类型擦除)

    = new Integer[]{1}; // 不报错 Integer[] ins2 = (Integer[]) objs2; } 类型擦除 java里的泛型是假泛型,只在编译期有效,在运行时是没有泛型的概念的...所以说java里面的泛型是假的,运行时不存在滴。 回归正题 数组不能向下强转我懂了,类型擦除我也懂了,似乎还是过不好这一生,呃不是,是还是解决不了这道题啊?...这就是关键所在,结合类型擦除,运行时并没有所谓的泛型,所以raw()返回的其实是Object,但是调用者自己知道我要的是String类型啊,所以我就知道强转一下喽。...泛型类呢? 我们上面举的例子都是泛型方法,那么泛型类呢?...总结 java中的泛型只在编译期有效,在运行时只有调用者知道需要什么类型,且调用者调用泛型方法后自己做强制转换,被调用者是完全无感的。

    51130

    Spring解决泛型擦除的思路不错,现在它是我的了。

    在 Spring 的官方文档中,关于泛型类型的事件通知只有寥寥数语,但是提到了两个解决方案: https://docs.spring.io/spring-framework/reference/core...因为泛型擦除,所以导致直接监听 EntityCreatedEvent事件是不生效的,因为在泛型擦除之后,EntityCreatedEvent变成了 EntityCreatedEvent。...然后用 data 对应的真正的 T 对象实例的类型,作为返回值,这样泛型对应的真正的对象类型,就在运行期被动态的获取到了,从而解决了编译阶段泛型擦除的问题。...和泛型擦除的关系已经不大了,我就不再写一次了。...核心逻辑就在 ResolvableTypeProvider 接口里面,重写了 getResolvableType 方法,在运行期动态的获取泛型对应的真正的对象类型,从而解决了编译阶段泛型擦除的问题。

    20710

    当类的泛型相关时,如何在两个泛型类之间创建类似子类型的关系呢

    Integer(10)); // OK someMethod(new Double(10.1)); // OK 当然泛型也是如此,在执行泛型类型调用时,将Number作为其类型参数传递,如果参数是...那么问题来了,当类的泛型相关时,如何在两个泛型类之间创建类似子类型的关系呢?例如如何让Box 和Box变得与Box有关呢?...小结:可以通过继承泛型类或者实现接口来对其进行子类型化。 搞懂了子类型化的问题,我们回到“如何在两个泛型类之间创建类似子类型的关系“的问题。...泛型类或者接口并不会仅仅因为它们的类型之间有关系而变得相关,如果要达到相关,我们可以使用通配符来创建泛型类或接口之间的关系。...extends Number> 因为Integer是Number的子类型,numberBox的泛型是Number对象子类,所以在intBox和numberBox之间存在关系。

    2.9K20

    那些年我们在Java泛型上躺过的枪---万恶的泛型擦除【享学Java】

    请注意参数化类型和方法参数类型的区别~ 泛型类 对比下面两个类,一个是普通类,一个是泛型类: class Generics { Object k; Object v; public...(T t) { return t; } } 静态方法使用泛型参数需要自己单独声明,否则编译报错。...粗细粒度需要控制好~ 泛型擦除 前面指出了,Java的泛型是假的,它是编译期的。...本例说明了:当我们声明List和List时,在运行时实际上是相同的,都是List,而具体的类型参数信息String和Integer被擦除了。...所以Java使用这么具有局限性的泛型实现方法就是从非泛化代码到泛化代码的一个过渡,以及不破坏原有类库的情况下,将泛型融入Java语言。 泛型通配符 和<?

    99030
    领券