From: Lew on 7 Jun 2010 18:56 Kevin McMurtrie wrote: >>> It can lead to ClassCastException on nonexistent lines. Lew wrote: >> What do you mean? Kevin McMurtrie wrote: > Doh! I accidentally sent before I finished. > > Generics can break inheritance. For example, the generics declaration > below demands that an override of put() take only a String as the key. > At the same time, HashMap without generics must take an Object as a key. > The compiler fixes this by adding a hidden method. It adds an override method, but that's not so weird. > This compiles with a warning: > > public class SnoopingMap<V> extends java.util.HashMap<String, V> > { > @Override > public V put(String key, V value) > { > System.out.println(key + " -> " + value); > return super.put(key, value); > } > > public static void main (String args[]) > { > SnoopingMap m= new SnoopingMap(); > m.put(new Integer(4), new Integer(5)); > } > } > > But fails to run with an error on a bogus line number: > > Exception in thread "main" java.lang.ClassCastException: > java.lang.Integer cannot be cast to java.lang.String > at SnoopingMap.put(SnoopingMap.java:1) I see what you mean by "bogus" line number, though I would not have chosen such an emotion-laden term myself. > at SnoopingMap.main(SnoopingMap.java:13) And there's your real error. > The javap utility shows the hidden method: > public java.lang.Object put(java.lang.Object, java.lang.Object); > Signature: (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; > Code: > 0: aload_0 > 1: aload_1 > 2: checkcast #16; //class java/lang/String > 5: aload_2 > 6: invokevirtual #17; //Method > put:(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; > 9: areturn > > LineNumberTable: > line 1: 0 > > > That translates to this code, which will not compile if you add it > yourself: > > public Object put(Object key, Object value) > { > return put((String)key, value); > { Adding that method by hand won't compile because it's erasure-equivalent to an override and doesn't conform to the generics requirements, and you can't have two erasure-equivalent methods in the same class. They have to have some method for doing type erasure. From what you show it's done by creating an override that does the class cast that you would have to have done by hand in pre-generics times. This does illustrate perfectly why you should avoid raw types - it defeats the purpose of generics and leads to ClassCastException to use them. -- Lew
From: Daniel Pitts on 7 Jun 2010 20:04 On 6/6/2010 5:38 PM, markspace wrote: > Daniel Pitts wrote: > >> List<? extends Object> list = new ArrayList<String>(); // compiles fine > >> List<? extends Object> list = new ArrayList<String>(); >> This says "A reference to a List which can have any Object retrieved, >> but only objects of an unknown type can be added, is assigned a List >> which can only have Strings added and retrieved. " > > > Small note: Since Object is the upper bound of all objects, <? extends > Object is the same as just <?>: > > List<?> list = new ArrayList<String>(); > > And of course for either both <?> and <? extends Object>, any generic > type on the right hand side is compatible and can be assigned. > > Also, "only objects of an unknown type can be added" isn't quite > correct. Since the type is unknown, you can't add any types, period. > (Except possibly null, I'd have to check.) You can only remove Objects. You can't have an untyped reference, so I don't think the distinction is useful. Let me know the result of your test, I'd be interested in seeing it, and I'm too lazy/busy right now to right my own SSCCE. -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Arne Vajhøj on 7 Jun 2010 20:48 On 07-06-2010 20:04, Daniel Pitts wrote: > On 6/6/2010 5:38 PM, markspace wrote: >> Daniel Pitts wrote: >>> List<? extends Object> list = new ArrayList<String>(); // compiles fine >> >>> List<? extends Object> list = new ArrayList<String>(); >>> This says "A reference to a List which can have any Object retrieved, >>> but only objects of an unknown type can be added, is assigned a List >>> which can only have Strings added and retrieved. " >> >> Small note: Since Object is the upper bound of all objects, <? extends >> Object is the same as just <?>: >> >> List<?> list = new ArrayList<String>(); >> >> And of course for either both <?> and <? extends Object>, any generic >> type on the right hand side is compatible and can be assigned. >> >> Also, "only objects of an unknown type can be added" isn't quite >> correct. Since the type is unknown, you can't add any types, period. >> (Except possibly null, I'd have to check.) You can only remove Objects. > You can't have an untyped reference, so I don't think the distinction is > useful. > > Let me know the result of your test, I'd be interested in seeing it, and > I'm too lazy/busy right now to right my own SSCCE. If you mean add null, then it works. Arne
From: Roedy Green on 9 Jun 2010 09:22 On Sun, 6 Jun 2010 04:02:19 -0700 (PDT), Vikram <vikrampyati(a)gmail.com> wrote, quoted or indirectly quoted someone who said : > >In java generics, the following code gives compile time error. > >List<Object> list = new ArrayList<String>(); // compile time error > >Where as the following does not give any compile time error > >List list = new ArrayList<String>(); > > >If no generics is specified, isin't it implied that it contains >object? What is the reason the second statement does not give any >compile time error? The problem comes because generics are implemented with purely compile-time checking. There is no record of the generic typing information available at run time. I think this was a mistake, but too late now. So there is on way Java could do a run-time check to make sure you did not add a Date to your List. The compiler can't reliably follow your logic at compile time to know that list is REALLY an ArrayList<String>, so it can't put in a compile time check to make you did not add a Date to your List. It goes by the type of List. -- Roedy Green Canadian Mind Products http://mindprod.com Have you ever noticed that any computer search in the movies, is always linear, with, for example, candidate fingerprints flashing up on the screen one after another? The public is still under the delusion that electronic files are microscopic filing cabinets made out of tiny wires or magnetic patches inside the computer. Most lay people are surprised that it is easy for a computer to file things simultaneously by a dozen different schemes, and that they can have any report printed in any number of different sorted orders. With physical files, they are limited to one ordering/access.
First
|
Prev
|
Pages: 1 2 3 Prev: logging into site using form validation http components Next: documentation versus contract |