zoukankan      html  css  js  c++  java
  • Java泛型

    Java泛型

    1、(2)以下的泛型转换,不正确,是一种编译错误。

    Let's test your understanding of generics. Is the following code snippet legal?

    List<String> ls = new ArrayList<String>(); // 1
    List<Object> lo = ls; // 2 
    

    Line 1 is certainly legal. The trickier part of the question is line 2. This boils down to the question: is a List of String a List of Object. Most people instinctively answer, "Sure!"

    Well, take a look at the next few lines:

    lo.add(new Object()); // 3
    String s = ls.get(0); // 4: Attempts to assign an Object to a String!
    

    Here we've aliased ls and lo. Accessing ls, a list of String, through the alias lo, we can insert arbitrary objects into it. As a result ls does not hold just Strings anymore, and when we try and get something out of it, we get a rude surprise.

    The Java compiler will prevent this from happening of course. Line 2 will cause a compile time error.

    参考:http://docs.oracle.com/javase/tutorial/extra/generics/subtype.html

    2、Wildcards

    So what is the supertype of all kinds of collections? It's written Collection<?> (pronounced "collection of unknown"), that is, a collection whose element type matches anything. It's called a wildcard type for obvious reasons. We can write:

    void printCollection(Collection<?> c) {
        for (Object e : c) {
            System.out.println(e);
        }
    }
    

    and now, we can call it with any type of collection. Notice that inside printCollection(), we can still read elements from c and give them type Object. This is always safe, since whatever the actual type of the collection, it does contain objects. It isn't safe to add arbitrary objects to it however:

    Collection<?> c = new ArrayList<String>();
    c.add(new Object()); // Compile time error
    

    Since we don't know what the element type of c stands for, we cannot add objects to it. The add() method takes arguments of type E, the element type of the collection. When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don't know what type that is, we cannot pass anything in. The sole exception is null, which is a member of every type.

    3、Bounded Wildcards

    Any drawing will typically contain a number of shapes. Assuming that they are represented as a list, it would be convenient to have a method in Canvas that draws them all:

    public void drawAll(List<Shape> shapes) {
        for (Shape s: shapes) {
            s.draw(this);
       }
    }
    

    Now, the type rules say that drawAll() can only be called on lists of exactly Shape: it cannot, for instance, be called on a List<Circle>. That is unfortunate, since all the method does is read shapes from the list, so it could just as well be called on a List<Circle>. What we really want is for the method to accept a list of any kind of shape:

    public void drawAll(List<? extends Shape> shapes) {
        ...
    }
    

    There is a small but very important difference here: we have replaced the type List<Shape> with List<? extends Shape>. Now drawAll() will accept lists of any subclass of Shape, so we can now call it on aList<Circle> if we want.

    List<? extends Shape> is an example of a bounded wildcard. The ? stands for an unknown type, just like the wildcards we saw earlier. However, in this case, we know that this unknown type is in fact a subtype of Shape. (Note: It could be Shape itself, or some subclass; it need not literally extend Shape.) We say that Shape is the upper bound of the wildcard.

    There is, as usual, a price to be paid for the flexibility of using wildcards. That price is that it is now illegal to write into shapes in the body of the method. For instance, this is not allowed:

    public void addRectangle(List<? extends Shape> shapes) {
        // Compile-time error!
        shapes.add(0, new Rectangle());
    }

    参考:http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

  • 相关阅读:
    Shell 中引用符号的名称及意义
    查看该目录下有几个文件夹几个文件的shell代码
    Linux下find 命令用法详解+实例
    Linux中echo的用法
    man help
    《鸟哥的linux私房菜》关于数据流重导向
    linux开机自动加载服务设置
    Shell调试技术总结(二)
    Shell中关于if,case,for,while等的总结
    硬盘的分区
  • 原文地址:https://www.cnblogs.com/tekkaman/p/6374399.html
Copyright © 2011-2022 走看看