public Class Erased<T>{ private final int SIZE = 100; public static void f(Object arg){ if(arg instanceof T){} // Error T var = new T(); // Error T[] array = new T[SIZE]; // Error T[] array = (T)new Object[SIZE]; // Unchecked warning } }
Erased.java 中创建类型实例无法实现,部分原因是因为擦除,而另一部分 原因是因为编译器不能验证T具有默认(无参)构造器。 Java中的解决方案是传递一个工厂对象,并使用它来创建新的实例。最便利的 工厂对象就是Class对象, 因此如果使用类型标签,就可以使用newInstance() 来创建这个类型的新对象
class ClassAsFactory<T> { T x; public ClassAsFactory(Class<T> kind){ try{ x = kind.newInstance(): }catch(Exception e){ ... } } } class Employee{} public class InstantiateGenericType { public static void main(String[] args){ ClassAsFactory<Employee> fe = new ClassAsFactory<Employee>(Employee.class); try{ ClassAsFactory<Integer> f1 = new ClassAsFactory<Integer>(Integer.class); }catch(Exception e){ ... } } }
可以编译,但是会因为ClassAsFactory<Integer>而失败,因为Integer没有任何
默认的构造器。 因为这个错误不是在编译期捕获的,所以不赞成,建议使用显式
的工厂,并将限制其类型,使得只能接受实现了这个工厂的类。
interface Factory1<T> { T create(); } class Foo2<T> { private T x; public <F extends Factory1<T>> Foo2(F factory){ x = factory.create(); } } class IntegerFactory implements Factory1<Integer> { public Integer create(){ return new Integer(0); } } class Widget { public static class Factory implements Factory1<Widget> { public Widget create(){ return new Widget(); } } } public class FactoryConstrain { public static void main(String[] args){ new Foo2<Integer>(new IntegerFactory()); new Foo2<Widget>(new Widget.Factory()) } }
这只是传递Class<T>的一种变体, 2种方式都传递了工厂对象, Class<T>碰巧是
内建的工厂对象,而上面的方式创建了一个显式的工厂对象,但却获得了编译器检查。
另一个种方式是模板方法法设计模式,get()是模板方法,而create()是在子类
中定义的,用来产生子类类型的对象。
abstract class GenericWithCreate<T> { final T element; GenericWithCreate(){ element = create(); } abstract T create(); } class X{} class Creator extends GenericWithCreate<X> { x create(){ return new X(); } void f(){ sysout(element.getClass().getSimpleName()); } } public class CreatorGeneric { public static void main(String[] args){ Creator c = new Creator(); c.f(); } }
发表评论
-
仿真[汽车制造]
2012-02-13 01:26 697class Car{ private final i ... -
线程例子[Condition, SignlAll, await]
2012-02-09 22:05 1040package concurrency.waxomati ... -
生产者消费者[简单示例]
2012-02-09 21:38 663class Meal{ private final ... -
多路分发3
2012-02-05 23:16 839使用常量相关的方法 常量相关的方法允许我们为每个 ... -
多路分发2[使用enum分发]
2012-02-05 18:09 1911直接将RoShamBo1.java翻译为基于enum的版 ... -
多路分发
2012-02-05 02:06 1394多路分发 Number.plus(Number) ... -
使用Enum的自动贩卖机
2012-02-04 13:52 938public enum Input { NICKEL ... -
使用enum的责任链
2012-02-04 12:39 1193package enumerated; impor ... -
枚举类Enum,EnumSet,EnumMap
2012-02-04 02:00 1438EnumSet与HashSet相比,非常快。 p ... -
枚举类enum
2012-02-03 15:00 907一般来说,我们希望每个美剧实例能够返回对自身的描述, ... -
类的简化历[从内部类到匿名内部类]
2012-02-02 12:41 636Version1: public class DirL ... -
持有引用java.lang.ref 和 WeakHashMap
2012-02-02 01:27 984Thinking in java P554 持 ... -
Collections快速报错 fial-fast
2012-02-02 00:46 803{ public static void main( ... -
散列HashCode
2012-02-01 14:04 713散列的价值在于速度: 散列使得查询快速,由于瓶颈位于键 ... -
使用散列数据结构注意点
2012-02-01 01:32 593Goundhog自动继承基类Object,所以这里使用 ... -
Set注意点
2012-02-01 01:31 318如果我们尝试着将没有恰当支持不许的操作的类型用于需要这些 ... -
享元Map
2012-01-30 00:28 384这里之所以叫享元,注意static关键字。 定制了Entry ... -
深入容器Map
2012-01-19 15:12 402Map生成器 对Map的使用相同的方式,需要一 ... -
深入容器List
2012-01-19 14:40 347一种Generator解决方案: 所有Collect ... -
泛型数组
2012-01-19 00:57 644不能创建泛型数组,但能通过转型来赋予 public cl ...
相关推荐
类型参数是在定义类时使用的占位符,实际的类型在创建类的实例时指定。例如,我们可以创建一个名为`GenericContainer<T>`的泛型类,其中`T`就是类型参数。这个类可以存储任何类型的对象,但具体类型在实例化时确定。...
在C#编程语言中,泛型集合是一种强大的工具,它允许开发者创建类型安全的数据结构,无需显式地指定存储的数据类型。泛型集合提供了一种高效且灵活的方式来处理各种类型的数据,同时保持了编译时的类型检查。下面将...
通过实际的代码示例,我们可以看到如何创建、实例化和使用泛型委托,以及它们如何帮助我们编写更简洁、更具可维护性的代码。 在“泛型委托”这个压缩包文件中,可能包含了以下内容: 1. **定义泛型委托**:首先,...
泛型(Generics)是一种在编程中引入的模板机制,用于在定义数据结构或方法时创建类型参数。这些参数可以在实例化时替换为具体的类型,使得容器(如List、Set、Map等)能够存储特定类型的元素,而不是任意类型。...
Java泛型是在JDK 5中引入的一种新特性,用于创建参数化类型,也就是说,可以在类、接口和方法中定义类型参数。泛型提供了类型安全的集合以及避免了显式类型转换的需要。使用泛型可以实现类型安全的数据结构,如List...
10. **泛型与反射**:通过反射,我们可以动态地创建泛型类型实例,获取和设置泛型类型字段,调用泛型方法等。这对于构建元编程和动态代码生成的场景非常有用。 总的来说,C#泛型的应用实例非常广泛,从简单的数据...
例如,我们可以通过类型名称获取类型实例,然后调用其公共方法: ```csharp Type type = Type.GetType("System.IO.File"); MethodInfo method = type.GetMethod("WriteAllText"); method.Invoke(null, new object[]...
在Visual Studio 2008(VS2008)中,开发者可以充分利用泛型来创建和使用数据结构,而无需担心类型转换带来的潜在错误。本文将详细探讨泛型的概念、优点以及如何在VS2008中使用泛型集合。 首先,我们需要理解什么是...
C++泛型编程是C++语言中的一个重要特性,它允许开发者编写不依赖特定类型而具有通用性的代码。这种编程范式极大地提高了代码的重用性和灵活性,降低了维护成本。本篇将深入探讨C++泛型编程的应用实例,帮助初学者...
4. 介绍泛型集合List,并创建一个实例,指定具体的数据类型。 5. 演示如何在List中添加、删除和访问元素,展示其类型安全和性能优势。 6. 对比ArrayList和List在内存使用和性能上的差异,解释为何在ASP.NET开发中...
在Java泛型应用实例中,我们可以看到泛型如何帮助我们提高代码的灵活性和效率,减少运行时的类型检查和强制转换。 首先,让我们理解泛型的基本概念。泛型主要由两部分组成:类型参数和类型边界。类型参数是在类或...
- **ActionSupport**:Struts2的ActionSupport基类并不直接使用泛型,但开发者可以创建自己的泛型Action,用于指定返回值类型,增强代码可读性和类型安全性。 - **结果映射**:在配置Struts2的Result类型时,可以...
本文将详细讲解如何使用C#创建线程、匿名委托以及泛型委托,并通过实例来阐述这些概念。 首先,让我们理解什么是线程。在多任务操作系统中,线程是程序执行的基本单元,它允许程序同时执行多个任务。在C#中,我们...
当我们创建`GenericStack`的实例时,可以指定具体的类型,如`GenericStack<Integer>`或`GenericStack<String>`。 接下来,我们讨论泛型接口。泛型接口与泛型类相似,只是它们定义在接口中。例如,我们可以定义一个...
- 类型擦除会导致一些限制,比如不能创建泛型数组,因为数组的类型在运行时是确定的。 5. **泛型与集合** - 泛型主要应用于集合框架,如`List`, `Set`, `Map`等。使用泛型可以确保添加到集合中的元素类型与集合...
派生约束where T : TI(T要继承自TI),构造函数约束where T : new()(T可以实例化),然后创建创建一个公共方法CreateInstance,实例化接口,输出指定泛型的类型,创建泛型接口完毕,源码完整供C#新手下载。
在实例文件中,你可能还会看到如何在实际代码中使用这个泛型类,例如创建实例并调用它的方法,以及验证泛型类型参数是否正确地实现了接口。此外,由于提供了编译后的执行文件,你可以直接运行程序来观察其效果,...
正确的方式是先创建非泛型数组,然后通过类型转换赋值给泛型引用: ```java List[] stringLists = (List[]) new List[]{new ArrayList()}; ``` 通过上述实例,我们可以了解到泛型在提高代码安全性和可读性方面...
- 这使得在运行时可以进行一些泛型相关的操作,如创建参数化的类实例。 总结来说,Java泛型的类型擦除虽然在运行时消除了类型信息,但通过编译时的类型检查、桥接方法、通配符等补偿机制,仍然实现了强大的类型...
在`Generic_InterfaceDemo`项目中,我们可以创建一个简单的程序,利用泛型接口处理不同类型的数据。例如,创建一个处理数字和字符串的类,并实现`IMyGenericInterface`: ```csharp public class NumberProcessor :...