只是在Java中使用泛型和东西,遇到了一个潜在的问题。这是我正在思考的简化版本
public class Test<T> {
private T[] arrayOfGenerics;
int top;
public Test(int size) {
arrayOfGenerics = (T[]) new Object[size];
top = 0;
}
public void add(T toAdd) {
arrayOfGenerics[top++] = toAdd;
}
public static void main(String[] args) {
Test myTest = new Test(10);
myTest.add("Some String"); //First value added is a String
myTest.add(12); //Way to make this NOT work, since myTest should only accept Strings now
}
}
显然,这并没有多大用处,生产方面明智,但我想更复杂的数据结构,你想要具有泛型的灵活性,但仍然强制它们都必须是相同的类型。这是一种解释它的可怕方式,但回到上面的示例代码,是否有办法使它成为当有人实例化和Test的实例时,他们必须指定arrayOfGenerics
的类型和是通过构造函数以某种方式坚持它,或者可能只是基于添加的第一种类型的值?
另一种解释它的方法,比如你正在实现自己的Stack或LinkedList数据结构。您希望它是所有相同类型的对象的堆栈。它可以是字符串,整数,等等,但它必须选择&#39;一个并坚持下去。
答案 0 :(得分:4)
我认为你没有在这里有效地使用泛型。对于前者执行以下操作:
// With this statement, the types that can be contained in the
// instance is fixed now.
Test<String> myTest = new Test<>(10);
myTest.add("Some String"); // this will work
myTest.add(12); // this won't compile
您确实声明Test
具有泛型类型,但是,在原始代码中,您在构造实例时没有使用它。这实际上导致Test<Object>
的实例。
在Java中,泛型被改装,并且由于他们不想破坏向后兼容性,他们必须允许构建“原始”实例。但是,编译器仍应提供有关“原始类型”的警告,并且可能IDE会要求您使用@SuppressWarnings("unchecked")
明确表示您使用的是非参数化类型。
至于强制用户确保他们输入正确的类型,您可以做的最好的是运行时检查。也就是说,对于前者。构造函数可以将Class
作为参数。在所有方法中,您确保给定的参数类型正确。但这并没有给你编译时检查。错误只能在运行时知道。
另一件事是,一旦确定使用泛型正确设计了API,您可能不必担心强制执行类型。如果API的用户不想使用特定类型,无论编译器发出警告,他们可能确实想要使用原始类型(或者,也许,他们不知道更好,他们还没有读过Effective Java)。即使是Java自己的API也不会在该领域做出任何额外的努力。对于前者以下代码有效,并且不会在运行时抛出任何异常:
List list = new ArrayList<String>();
list.add("xyz");
list.add(123);
答案 1 :(得分:0)
如果要创建全班,则必须为班级指定
Generic
类型为Test<String> myTest = new Test<>(10);
包含相同类型的对象。
然后您的课程无法添加其他类型的Objects
。请参阅以下示例。
Test<String> myTest = new Test(10);
myTest.add("Some String"); //works fine
myTest.add(12); //not works
您已将数组的大小设置为Constructor
。因此,您不能超过指定的大小。请执行以下修改以使大小随机。
//constructor
public Test() {
top = 0;
arrayOfGenerics = (T[]) new Object[top];
}
//add method
public void add(T toAdd) {
top++;
T[] newArray = (T[]) new Object[top];
newArray[top - 1] = toAdd;
System.arraycopy(arrayOfGenerics, 0, newArray, 0, top - 1);
arrayOfGenerics = newArray;
}