How exactly do Generics work?

前端 未结 2 768
無奈伤痛
無奈伤痛 2020-12-28 17:44

While looking up (testing) information for another question, I came across something and had completely no clue why it was happening. Now, I know that there is no practical

2条回答
  •  灰色年华
    2020-12-28 18:23

    The crux of the question is:

    And why is it fine for the println() method to call its toString, but not for me to directly?

    ClassCastException exception isn't occurring due to calling toString() but due to an explicit cast added by the compiler.

    A picture is worth thousand words, so let's look at some decompiled code.

    Consider following code:

    public static void main(String[] args) {
        List s = new ArrayList();
        s.add("kshitiz");
        List i = new ArrayList(s);
    
        System.out.println(i.get(0)); //This works
        System.out.println(i.get(0).toString()); // This blows up!!!
    }
    

    Now look at the decompiled code:

    public static void main(String[] args) {
        ArrayList s = new ArrayList();
        s.add("kshitiz");
        ArrayList i = new ArrayList(s);
        System.out.println(i.get(0));
        System.out.println(((Integer)i.get(0)).toString());
    }
    

    See the explicit cast to Integer? Now why didn't compiler add a cast in previous line? The signature of the method println() is:

    public void println(Object x)
    

    Since println is expecting an Object and result of i.get(0) is Object no cast is added.

    It is also okay for you to invoke toString(), granted that you do it like this so that no cast is generated:

    public static void main(String[] args) {
        List s = new ArrayList();
        s.add("kshitiz");
        List i = new ArrayList(s);
    
        myprint(i.get(0));
    }
    
    public static void myprint(Object arg) {
        System.out.println(arg.toString()); //Invoked toString but no exception
    }
    

提交回复
热议问题