泛型擦除补偿

由于在使用泛型的时候,将会擦除类型参数,而只保留原始类型。所以在使用泛型时,我们不能使用new T(),也不能使用instanceof, 因为这两类操作要知道确切的类型。此问题的解决方案有三种(设计模式的使用):简单工厂(最简单),工厂方法(最灵活),模板方法(最简捷)。

1.简单工厂

在此方法中,将类型作为参数,以一个万能的工厂类(其中有一个返回具体类型类的实例的泛型方法)用类的newInstance()方法返回参数化类型的实例,如下所示:

优点:简单,直接使用泛型方法

缺点:

(1)单一使用Class对象的newInstance()方法只能使用默认的构造器,使得对象的创建有限制。

(2)若一个具体的类无默认的构造器,则会抛出异常。

2.工厂方法

与简单工厂方法相比,工厂方法加入了如下几个元素:

(1)工厂接口/抽象接口—具体工厂公共的接口/类型

(2)具体工厂—–由具体工厂负责具体产品的创建,且其必须保证产品的成功的创建,在具体工厂中可调用各种各样的构造方法,因为具体工厂中已将参数化类型具体化。

(3)工厂管理类——由此类可负责何种类型具体工厂的创建并可返回具体工厂的实例。

优点:加入了上述三个元素后,解决了以下问题:

1)所有的具体工厂拥有共同的接口

2)具体工厂保证了具体产品的成功创建:可调用任意的构造方法生成具体类的实例

3)工厂管理类:对具体工厂的生成拥有控制权,使具体工厂的生成具有了灵活性。

工厂方法的实现如下:

1)抽象工厂

2)AuthorFactory:负责Author实例的创建

3)IntegerFactory:负责Integer实例的创建

3)工厂管理类(泛型类):FactoryManage

4)测试客户端

补充:具体的Author类

3.模板方法

以更加简捷的方法生成具体类的实例。与工厂方法不同的地方在于:用模板类(抽象类)来控制整个实例化过程的流程(有点像工厂管理类,由模板方法控制整体流程,而具体创建过程由其子类实现),而由具体类来完成具体产品的构建。但在具体生成类的实例时,我还是用到了工厂的概念,但其只作为一个具体的实现而已。最大的优点:简捷,因为直接调用具体的生成类即可,并且模板类是隐藏的,对客户透明的(而工厂方法中管理类工厂要显式地生成)。

3.1模板类

3.2具体模板类AuthorCreator

3.3具体模板类:IntegerCreator

3.4客户端测试

时间: 2024-08-29 10:14:13

泛型擦除补偿的相关文章

java泛型擦除的神秘之处,边界处的动作,擦除的补偿

java泛型擦除的神秘之处 package org.rui.generics.erasure; public class HasF { public void f(){ System.out.println("hasf.f"); } } package org.rui.generics.erasure; /** * 边界 <T extneds Hasf>声明T必须具有类型HasF或者从Hasf导出的类型. * 如果情况确实如此,那么就可以安全地在obj上调用f()了 * T

Java中泛型区别以及泛型擦除详解

一.引言 复习javac的编译过程中的解语法糖的时候看见了泛型擦除中的举例,网上的资料大多比较散各针对性不一,在此做出自己的一些详细且易懂的总结. 二.泛型简介 泛型是JDK 1.5的一项新特性,一种编译器使用的范式,语法糖的一种,能保证类型安全.[注意:继承中,子类泛型数必须不少于父类泛型数] 为了方便理解,我将泛型分为普通泛型和通配泛型 三.泛型分类 1.普通泛型 就是没有设置通配的泛型,泛型表示为某一个类. 声明时: class Test<T>{...} 使用时: Test<Int

泛型擦除 反射 自动装配

1.泛型擦除 package cn.itcast.demo; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; public class Demo1 { public static void main(String[] args) throws SecurityExceptio

泛型深入--java泛型的继承和实现、泛型擦除

泛型实现类: package generic; /** * 泛型父类:子类为“富二代”:子类的泛型要比父类多 * 1,保留父类的泛型-->子类为泛型类 * 2,不保留父类泛型-->子类按需实现 * * * 子类[重写方法]的参数类型 -->随父类而定 * 子类新增的方法,参数类型随子类而定 * 子类中使用父类的[属性] -->随父类而定 * 子类使用自己的属性-->随子类而定 * @author Administrator * */ public abstract class

Java泛型擦除

Java泛型擦除: 什么是泛型擦除? 首先了解一下什么是泛型?我个人的理解:因为集合中能够存储随意类型的对象.可是集合中最先存储的对象类型一旦确定后,就不能在存储其它类型的对象了,否则,编译时不会报错.但执行时会抛出ClassCastException异常.为解决此问题,引入泛型,指定该集合对象中存储的对象类型,这样一旦该集合中存储了其它的对象类型,编译时会提示错误!(理解不当之处.希望大神多指点). 泛型的擦除就是说.在编译的时候集合中指定了确定的对象类型,但在执行时将集合中能够存储的该对象类

跟王老师学泛型(八):泛型擦除与转换

泛型擦除与转换 主讲教师:王少华 QQ群:483773664 学习目标: 掌握泛型擦除的含义 理解泛型转换的规则 一.泛型擦除 (一)什么泛型擦除 Java中的泛型基本上都是在编译器这个层次来实现的.在生成的Java字节码中是不包含泛型中的类型信息的.也就是说虚拟机中没有泛型,只有普通类和普通方法 使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉.这个过程就称为类型擦除. 类型擦除的主要过程如下:     1.将所有的泛型参数用其最左边界(最顶级的父类型)类型替换.     2.移除所有

Java 之 泛型擦除

泛型擦除 在严格的泛型代码里,带泛型声明的类总应该带着类型参数.但为了与老的 Java 代码保持一致,也允许在使用带泛型声明的类时不指定类型参数.如果没有为这个泛型类指定泛型参数,则该类型参数被称作一个原始类型(raw Type). 如果在使用泛型类或泛型接口的时候,没有指定泛型实参,会怎么样?(泛型擦除现象,泛型擦除后,泛型形参被解析为什么类型呢?) (1)如果没有指定泛型形参的上限,就按照 Object 处理: (2)如果指定泛型形参的上限,就按照上限处理,如果有多个上限,多个上限用&连接,

泛型擦除

Java泛型的处理几乎都在编译器中进行,编译器生成的bytecode是不包涵泛型信息的,泛型类型信息将在编译处理是被擦除,这个过程即类型擦除. http://blog.csdn.net/caihaijiang/article/details/6403349

关于泛型擦除的知识(来源于csdn地址:https://blog.csdn.net/briblue/article/details/76736356)

泛型,一个孤独的守门者. 大家可能会有疑问,我为什么叫做泛型是一个守门者.这其实是我个人的看法而已,我的意思是说泛型没有其看起来那么深不可测,它并不神秘与神奇.泛型是 Java 中一个很小巧的概念,但同时也是一个很容易让人迷惑的知识点,它让人迷惑的地方在于它的许多表现有点违反直觉. 文章开始的地方,先给大家奉上一道经典的测试题. List<String> l1 = new ArrayList<String>(); List<Integer> l2 = new Array