关于泛型的类型安全就这么多了

发布于 2024-10-08 02:57:11 字数 454 浏览 2 评论 0原文

有一些奇怪的事情让我无法理解。一般来说,泛型是一件好事。它在编译时提供类型安全。例如:

class A{}

class B{}

static void someMethod() {
    List<B> listB = new ArrayList<B>();
    listB.add(B);
    listB.add(A); // here goes a compiler error

    // but this will compile fine
    List<Object> objList = new ArrayList<Object>();
    objList.add("String");
    objList.add(new Integer(9));
    objList.add(B);
}

嗯,这是 Java 开发人员错过的东西吗?

There is something strange I can't wrap my head about. Generics is a good thing in general. It gives a type-safety at compile time. For example:

class A{}

class B{}

static void someMethod() {
    List<B> listB = new ArrayList<B>();
    listB.add(B);
    listB.add(A); // here goes a compiler error

    // but this will compile fine
    List<Object> objList = new ArrayList<Object>();
    objList.add("String");
    objList.add(new Integer(9));
    objList.add(B);
}

Well, is it something Java developers missed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

明月松间行 2024-10-15 02:57:11

Object 是所有事物的基类,您正在添加 Object 类型的对象。因此类型安全(因为所有插入的对象都满足对象类型的要求)。

Object is the base class of everything and you are adding objects of type Object. Therefore type safe (as all inserted objects fulfill the requirement of being of type object).

望笑 2024-10-15 02:57:11

如果您创建对象列表,则您可以添加对象。这就是为什么您可以添加 StringIntegerB 的实例...它们都是对象!

也许您想知道为什么不允许添加对象。嗯,允许添加子类型会非常方便。例如,考虑您想要在列表中存储大量数字。你不知道它们是浮点数还是整数等。那么你可以这样做

List<Number> numList = new ArrayList<Number>();
numList.add(new Double(5.5));
numList.add(new Integer(5));
numList.add(new Long(10L));

If you create a list of Objects, you're allowed to add Objects. That's why you can add instances of String, Integer and B... they are all objects!

Perhaps you wonder why one is not only allowed to add Objects. Well, it can be quite handy to allow for subtypes to be added. Consider for instance that you want to store lots of numbers in a list. You don't know if they are floating point numbers or integers etc. Then you could do

List<Number> numList = new ArrayList<Number>();
numList.add(new Double(5.5));
numList.add(new Integer(5));
numList.add(new Long(10L));
演多会厌 2024-10-15 02:57:11

简单来说,"String" new Integer(9)BObject,而 B 不是 A

在继承中,如果
A 扩展了 B,那么 A 也被称为类型AB
Object是所有类的超类。

In simple words, "String" new Integer(9) and B are Object, whereas B is not A.

In inheritance, if
A extends B, then A is said to be of typeAandBas well;
Objectis thesuper` class of all the class.

溺孤伤于心 2024-10-15 02:57:11

本质上:

List l = new ArrayList();

是这样解释的

List<Object> l = new ArrayList<Object>();

,事实上,向这个列表中添加任意对象都可以。这应该在编译时发出警告,因为您使用的是不带参数的参数化类型。

以这种方式实现是为了保持向后兼容性。如果所有使用 new ArrayList()(或任何其他集合框架类)的非参数化代码突然无法编译,那么将花费大量的时间和金钱来修复。是的,这意味着您可以编写不安全的代码,但您会收到警告,并且至少您现有的 1000 万行应用程序仍然可以工作。

Essentially:

List l = new ArrayList();

is interpreted as

List<Object> l = new ArrayList<Object>();

so, in fact, adding arbitrary Objects to this list is fine. This should emit a warning when it is compiled because you are using a parameterised type with no parameters.

It was implemented this way to preserve backward compatibility. If all non-parameterised code that used new ArrayList() (or any other collections framework class) suddenly didn't compile then that would cost an enormous amount of time and money to fix. Yes, it means you can write unsafe code, but you get warned about it and at least your existing 10-million-line application still works.

萧瑟寒风 2024-10-15 02:57:11

Java 泛型确实提供了适当的类型安全性,但您没有适当地指定边界。这是泛型实际上为您提供的一个示例:

List<Number> list1 = new ArrayList<Number>();
list1.add(new Integer(1)); // can add anything that is a Number
list1.add(new Double(1.0));
Number n = list1.get(0); // and retrieve Numbers

List<? super Number> list2 =  new ArrayList<Number>(); // can be a list of number
list2 = new ArrayList<Object>(); // or a list of objects
list2.add(new Integer(1)); // but can only add numbers
list2.add(new Double(1.0));
Object o1 = list2.get(0); // and only retrieve Objects

List<? extends Number> list3 = new ArrayList<Number>(); // can be a list of numbers
list3 = new ArrayList<Integer>(); // or any subtype of Number
list3 = new ArrayList<Double>();
list3.add(null); // but can add any thing to it
Number n2 = list3.get(0); // and only retrieve Numbers

Java generics do provide proper type safety, but you are not specifying the boundaries appropriately. Here is an example what generics actually provide you with:

List<Number> list1 = new ArrayList<Number>();
list1.add(new Integer(1)); // can add anything that is a Number
list1.add(new Double(1.0));
Number n = list1.get(0); // and retrieve Numbers

List<? super Number> list2 =  new ArrayList<Number>(); // can be a list of number
list2 = new ArrayList<Object>(); // or a list of objects
list2.add(new Integer(1)); // but can only add numbers
list2.add(new Double(1.0));
Object o1 = list2.get(0); // and only retrieve Objects

List<? extends Number> list3 = new ArrayList<Number>(); // can be a list of numbers
list3 = new ArrayList<Integer>(); // or any subtype of Number
list3 = new ArrayList<Double>();
list3.add(null); // but can add any thing to it
Number n2 = list3.get(0); // and only retrieve Numbers
楠木可依 2024-10-15 02:57:11

您的第一个示例失败的原因是 A 不是 B`。

第二个示例之所以有效,是因为 Stringnew Integer(9)B 都是 Object

这具有良好的逻辑意义,并且出于其他发帖者所说的原因而实用。

the reason your first example fails is because A is not aB`.

the reason the second example works is because String, new Integer(9), and B are all Objects.

This makes good logical sense, and practical for the reasons other posters said.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文