1

Ok guys. This is a revision

class Node<E> { // (1)

  private E            data;    // Data                           (2)
  private Node<E>      next;    // Reference to next node         (3)
  Node(E data, Node<E> next) {                                 // (4)
    this.data = data;
    this.next = next;
  }

  public void    setData(E e)    {}   // (5)
  public void    xxxData(E e)    {}   // (6)
  public E       getData(E e)    {return null;}   // (7)

  public static void main(String [] args) {

      Node<? extends Integer> n1 = new Node<Integer>(1,null);  //8
      Node<? super Integer> n2 = new Node<Integer>(1,null);  //9

      n1.setData(new Integer(1));  //10 compiler error
      n1.xxxData(new Integer(1));  //11 compiler error
      n2.setData(new Integer(1));  //12 ok

  }

}

Here's a rewrite hopefully i can convey my confusion nicely.
1. n1 is upper bounded wildcard. So this wont allow adding of records. Clause 10 proves this.
2. clause 11 also proves that method names (in this case 'SET' to determine adding of records) not being used since xxxData method gives the same compiler error.
3. n2 is lower bounded wildcard. Since method names doesn't play a role here, how does compiler knows that setData method can be used on n2 (since n2 is a lower bounded wildcard and this wildcard allows for adding of records)? Basically what the difference on method setData on clause 10 and 12?

Bear in mind nothing happens in those methods. It's empty or returning null.

yapkm01
  • 3,590
  • 7
  • 37
  • 62
  • 5
    I'm puzzled about why there is a getData with an argument and a setData without one. Those are completely useless methods... – Dylan Sep 21 '11 at 19:49
  • 2
    If this question makes sense to anyone, can you please explain it to me? – erickson Sep 21 '11 at 20:05
  • 3
    "whether to do a set or a get"? It does whichever method you tell it to do! I must be misunderstanding the question. – Ed Staub Sep 21 '11 at 20:07
  • Still pretty confused. The compiler *doesn't* recognize that the method is for "adding". It just recognizes that the method has an argument. At least I can clear up one thing for you: method names are completely meaningless to the compiler. You can use Chinese ideograms if you want. – erickson Sep 21 '11 at 20:31

5 Answers5

1

If I understood your question properly, I guess it's because Integer is both super- and subtype to itself.

Victor Sorokin
  • 11,878
  • 2
  • 35
  • 51
  • That's kind of misleading, it's really that the notations `? extends T` and `? super T` both include `T`. Not sure if this is what you meant. – Paul Bellora Sep 21 '11 at 19:56
  • @Kublai That's how it is. "`? extends Shape` [...] is in fact a subtype of `Shape` [or] could be `Shape` itself, or some subclass; it need not literally extend `Shape`." ([Wildcards](http://download.oracle.com/javase/tutorial/extra/generics/wildcards.html)) "The syntax `? super T` denotes an unknown type that is a supertype of `T` (or `T` itself; remember that the supertype relation is reflexive)" ([More fun with Wildcards](http://download.oracle.com/javase/tutorial/extra/generics/morefun.html)) – kapex Sep 21 '11 at 20:24
  • @kapep - Yeah I know. I think you just better explained to me what I was trying to explain to Victor, who may or may not be on the same page as both of us. – Paul Bellora Sep 21 '11 at 20:29
1

Yes, you are confusing three things:

  1. java method names are just names, you can call them anything you want
  2. there is a convention in Java to use what are called getters and setters. If you have a field (data or next in your example), then you define two methods: .

    public void setData(E data) { this.data = data; }

    public E getData() { return this.data; }

This convention is called Java Beans. You'd do the same for node by the way.

3) Java selects the method to call based upon the types of the parameters that you pass to the method. This is called method overloading. It means that you can define things like:

public void setFile(String name) {
    // do something here
}

public void setFile(File file) {
   // do something here
}

so you can call:

setFile(new File("barbar"));

or

setFile("c:\stuff");

and the correct method will be chosen.

The generic types that you have just confuse the situation even more :-)

Matthew Farwell
  • 60,889
  • 18
  • 128
  • 171
0

Java doesn't care about get/set in the method name; it's all based on method parameter types. Consider

interface G<T>

    T f1();

    void f2(T t);

    void f3();

Substitute T with different types, methods signatures are changed too; for example, G<Int> methods

    Int f1();

    void f2(Int t);

    void f3();

So we can do the following

G<Int> o = ...;
Int i = o.f1();
o.f2(i);
o.f3();

What happens with wildcards? Actually compiler can't directly reason about wildcards; they must be replaced with fixed albeit unknown types; this process is called "wildcard capture".

For example, given a G<? super Int> type, compiler internally treats it as G<W>, where W is an unknown supertype of Int. G<W> has methods

W f1();

void f2(W t);

void f3();

So we can do

G<? super Int> o = ...;
Object i = o.f1();   // f1() returns W, which is subtype of Object
o.f2( new Int(42) ); // f2() accepts W; Int is a subtype of W, accepted.
o.f3();

Similarly

G<? extends Int> o = ...; // G<W>, where W is a subtype of Int
Int i = o.f1();      // f1() returns W, which is subtype of Int
o.f2( new Int(42) ); // error: f2() accepts W; Int is NOT a subtype of W
o.f3();
irreputable
  • 44,725
  • 9
  • 65
  • 93
0

I think i have the answer to this problem. It's true that method name doesn't play a role here but rather whether the reference assignment is valid.

Compiler error for clause 10 & 11 is due to the following in terms of parameter assignment.

? extends Integer = Integer

One cannot assign the Integer to ? extends Integer since the ? extends Integer could have type which is lower than Integer (figuratively speaking).

Of course this works for clause 12.

yapkm01
  • 3,590
  • 7
  • 37
  • 62
0

The question really changed now... The answer to this is PECS
(or here, page 28)

Also see, What is PECS (Producer Extends Consumer Super)? or How can I add to List<? extends Number> data structures?

Community
  • 1
  • 1
kapex
  • 28,903
  • 6
  • 107
  • 121