0

I am learning Java generic from: https://docs.oracle.com/javase/tutorial/java/generics/bounded.html and I have some doubts on the code sample below:

public class Box<T> {

    private T t;          

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }

    public <U extends Number> void inspect(U u) {
        System.out.println("T: " + t.getClass().getName());
        System.out.println("U: " + u.getClass().getName());
    }

    public static void main(String[] args) {
        Box<Integer> integerBox = new Box<Integer>();
        integerBox.set(new Integer(10));
        integerBox.inspect("some text"); // error: this is still String!
    }
}

Why wasnt the inspect() method to be written as shown below instead it was ?

 public <T extends Number> void inspect(T t) { }

There are some other code samples which has the following syntax. What does the 1st pair stands for?

public <K,V> SomeClass<K,V>

What does static stands for?

public static <T> int countGreaterThan(T[] anArray, T elem)
ilovetolearn
  • 2,006
  • 5
  • 33
  • 64
  • your example `public SomeClass` should be written `public class SomeClass` :) – freedev Jun 05 '17 at 09:58
  • `Why wasnt the inspect() method to be written as shown below instead it was ?` Same as why you can't have two fields with the same name: because `T` is already used for something else. – biziclop Jun 05 '17 at 10:13

3 Answers3

2

The method Box.inspect() expects a type that extends Number so it is not applicable when the argument is a String.

Box.inspect() is just an example of generic type applied to a method.

On other hand you have a class Box with generic type T, but you can also have a method that accepts another type U which is broader (upper bounded) than T.

The class itself does not say how to use inspect and why, it just give you the possibility to handle different types. Don't put great expectations by this sample.

Consider that it is a just a sample that explain how to use Generics (not great logic behind).

Regarding public class SomeClass<K,V> declaration, this a declaration with multiple generics types.

The class HashMap<K,V>() is a real sample of this case, K is the type for the key value and V is the type for the value.

freedev
  • 25,946
  • 8
  • 108
  • 125
0
public <U extends Number> void inspect(U u) {

waits for a parameter that is of Number type or a derived of it.
So you cannot of course pass a String value :

integerBox.inspect("some text"); // error: this is still String!

In your class, you declare two parameterized type :

  • one in the class declaration : public class Box<T> {

  • another in the public <U extends Number> void inspect(U u) method.

These set two distinct constraints.

When you declare an instance of Box with Integer as generic type:

Box<Integer> integerBox = new Box<>(); 

This following field using the T type will be associated to an Integer type :

private T t;          

but the public <U extends Number> void inspect(U u) method doesn't use the T type.
So you can use distinct types in the two cases:

    Box<Integer> integerBox = new Box<Integer>();
    integerBox.set(new Integer(10));
    integerBox.inspect(Float.valueOf(10)); // I pass a float and it is valid.

If you would declare the method in this way :

 public <T extends Number> void inspect(T t) { }

you would have the same behavior as T in the declared method would be another T type as which one declared in the class.
But this way is misleading as you use use twice the same type name (T) while these are distinct types.

Otherwise, to constraint the parameter of the method to the type declared in the class, you have not to declare still a type.

This is enough :

 public void inspect(T t) { }

Now you can only use the same type in the two cases:

    Box<Integer> integerBox = new Box<Integer>();
    integerBox.set(new Integer(10));
    integerBox.inspect(Float.valueOf(10)); // doesn't compile
davidxxx
  • 125,838
  • 23
  • 214
  • 215
-1

Yes. Freedev answer is correct. Try

public static void main(String[] args) {
    Test1<Integer> integerBox = new Test1<Integer>();
    integerBox.set(new Integer(10));
    integerBox.inspect(78); //  inspect method expect a interger value
}
Pradeep Singh
  • 1,094
  • 1
  • 9
  • 24