• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Generics

 
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
I am planning to take SCJP 5, but i am not able to get an hang on generics.

class Test
{

public static void main(String [] arg)
{

List<? extends Object> o2 = new ArrayList<Object>();

Test.ex1(o2,new Object()); //1
Test.ex2(o2); //2

List<? super Object> o3 = new ArrayList<Object>();
Test.ex1(03); //3
}



public static <T> T ex1(List<T> a,T a1)
{
T e = null;
a.add(e);
return null;
}


public static <T> T ex2(List<T> a)
{
T e = null;
a.add(e);
return null;
}

}

Please clarify as how line 2 and line 3 works whereas line 1 gives compiler error.
Am so confused with generics.Please help me.
 
Ranch Hand
Posts: 35
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Roopa,

first of all there are a couple of issues with your code. One of which is that it doesn't compile (it's also really hard to read...) Lets assume that
line 3 says Test.ex1(o3) and not Test.ex1(03)

Now... your question was:

Please clarify as how line 2 and line 3 works whereas line 1 gives compiler error.



Line 1 gives you an error because you are using the following syntax:

and you're passing o2 to ex1 which tries to add an object to o2. Remember a very important thing about extends: You can NOT add/manipulate a generic type that has extends in it! That's why line 1 is not compiling.

Of course that logic should apply to line 2... why it doesn't, and why you can actually add to the list in ex2 is beyond my understanding... I will dig deeper and if/when I find something I will post here... so stay tuned.

As for line 3, it's failing because ex1 takes two arguments. BUT if you add the extra parameter "new Object()" it will work fine because <? super Object> allows you to add to the list.
 
Roopa Maheshkumar
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the prompt reply. Am sorry for the typo's & the poor formatting i caused.

But i dont think that line1 fails because of the add method.
Even after commenting the add method.It still gives a compiler error.

public static <T> T ex1(List<T> a,T a1)
{
T e = null;
//a.add(e);
return null;
}

If i change line 3 to
Test.ex1(o3,new Object()); //3

I dont get a compiler error.

I am stunned that though there is no add method in ex1(), the extends declaration gives a compiler error whereas the super declaration compiles fine. Am going nuts with generics... please help me!!
 
Ranch Hand
Posts: 664
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Going nuts with Generics???

I am with you... It's
 
Ranch Hand
Posts: 210
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All,

In method call at line 1 parameters are ? extends Object and Object, so compiler will assume T as Object (nearest super type of both).

as we can not assign List<? extends Object> reference to List<Object>,so the code will not compile.

In method call at line 2, compiler will assume T as "? extends Object" so the code compiles and only null can be added to List.

Hope that helps..
[ May 30, 2008: Message edited by: ramesh maredu ]
 
Noam Wolf
Ranch Hand
Posts: 35
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's what ramesh said... but in a way I understand it.. hope it helps:

2 is compiling because that construction is perfectly ok. The method
accepts a List of anything effectively.

1 is not compiling because you are saying param1 should be of type
List<X> where X is a runtime type (the ? is a placeholder which is
filled in by X at runtime). Param2 is an object. Since the compiler
cannot confirm that argument2 (of type object) is of type X, it breaks
compilation.

Answer was given to me by Uber Java Engineer @ google...
 
Roopa Maheshkumar
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi...

Thanks for the replies. It helped me get an insight...but i have a doubt.

List<? extends Object> o2 = new ArrayList<Object>();

o2 cant be passed to List<Object> and hence the compilation error in line1

List<? super Object> o3 = new ArrayList<Object>();

I guess o3 too cant be passed to List<object>, but how is that line3 compiles without an error.

i am confused with this distinction between extends and super
 
Author
Posts: 986
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Noam Wolf:

you're passing o2 to ex1 which tries to add an object to o2. Remember a very important thing about extends: You can NOT add/manipulate a generic type that has extends in it! That's why line 1 is not compiling.



I beg to differ. Your statement in boldface is essentially correct, but
that has nothing to do with line 1 not compiling. Only the signatures
of the methods matter. Their bodies are irrelevant as far as main() is
concerned. In fact, the errors would be exactly the same if the code
were rewritten like this:

The error on line 1 is because the types of a's T and a1's T must be the
same and the compiler can't verify that. The compiler knows that the
argument passed for a1 has type Object, but knows nothing about the
List element type of o2 (except that it "extends Object," which isn't much).

Line 2 compiles without error. No issues, right?

The problem with line 3 has nothing to do with generics. It's just that
it is attempting to call the ex1() method with the wrong number of
arguments. Either test.ex1(o3, Boolean.TRUE) or test.ex2(o3)
would compile without error.

[edit: Made it so not the entire quote is bold, so one can tell which
sentence is the boldface sentence.]
[ June 01, 2008: Message edited by: Brian Cole ]
 
Roopa Maheshkumar
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Brian,

Thanks for the reply. But i have a doubt.

If i change the line 3 to take 2 parameters,it compiles fine, whereas line1 doesnt. Both the lines use wildcards... the only distinction is super and extends.But i am not clear why super compiles whereas extends doesnt when 2 parameters are passed.

List<? extends Object> o2 = new ArrayList<Object>();
test.ex1(o2, new Object()); // 1

List<? super Object> o3 = new ArrayList<Object>();
test.ex1(o3,new Object()); // 3
 
Ranch Hand
Posts: 486
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am also not getting guys. Please help to understand the concept
 
ramesh maredu
Ranch Hand
Posts: 210
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
List<? extends Object> o2 = new ArrayList<Object>();
test.ex1(o2, new Object()); // 1

above line will not compile because (compiler consider T as Object super type of ? extends Object and Object) we can not be assign List<? extends Object> reference to List<Object>

List<? super Object> o3 = new ArrayList<Object>();
test.ex1(o3,new Object()); // 3


The above code compiles because super type of "? super Object and Object" is ? super Object.and you can assign List<? super Object> to List<? super Object>

See my long reply to this

thread

[ June 02, 2008: Message edited by: ramesh maredu ]
[ June 02, 2008: Message edited by: ramesh maredu ]
 
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

AS POSTED BY NOAM
1 is not compiling because you are saying param1 should be of type
List<X> where X is a runtime type (the ? is a placeholder which is
filled in by X at runtime). Param2 is an object. Since the compiler
cannot confirm that argument2 (of type object) is of type X, it breaks
compilation.

Answer was given to me by Uber Java Engineer @ google...



But in kathy sierra book it is said that generics provide compile time protection
There is no such thing as runtime in case of generics?
Can someone please explain
I'm really confused?
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic