user1050619
user1050619

Reputation: 20856

Generics methods - passing objects and invoking its method

I'm trying to understand how Generics works and wrote a method to test it.

I have created Object - Drink and its child object Coffee... and defined a generic method go1() to invoke the sip() method of both these objects...

I'm running in Eclipse and get an error - stating the method sip() is undefined for type V.

Can someone explain how this is handled?

class Drink{
    public void sip(){
        System.out.println("Im Drink method");
    }
}

class Coffee extends Drink{
    public void sip(){
        System.out.println("Im Coffee method");
    }

}

public class test{

    public static <V> V go1(V o){
        o.sip();

    }

public static <V> void go(V v){
        System.out.println(v.hashCode());
    }

    public static void main(String[] args) {
        Drink s1 = new Drink();
        go1(s1);

            int i = 10;
        String j ="test";
        go(i);
        go(j);

    }
}

Upvotes: 0

Views: 150

Answers (4)

Rohit Jain
Rohit Jain

Reputation: 213261

Just add bounds to the type parameter:

public static <V extends Drink> void go1(V o){
    o.sip();
}

With type parameter bound, you get access to the non-static methods of the bound - Drink in this case, using the reference of that type parameter.

After edit:

For passing String and Integer to your method, you can think of which common upper bound would fit for both. The common supertype for String and Integer are:

So, you can have three kinds of bounds:

  • <V extends Object>
  • <V extends Serializable>
  • <V extends Comparable<V>>

So you just modify your go() method like:

public static <V extends Object> void go(V v){
    System.out.println(v.hashCode());
}

References:

Upvotes: 3

christopher
christopher

Reputation: 27346

Just to aid your understanding..

Given that your overall objective is to further your understanding of Generics, I'd just like to point out that a simple interface or superclass object reference would be a simpler solution to your issue. i.e:

public void go1(Drink d)
{
    d.sip();
}

A more classic example of Generics

Let's say you've got an object, Pair. Pair needs to be able to hold two of anything in Java, so you make those two things of type Object. What does that mean? It means you're always casting between Object and the desired type. So what do you do? You use generics.

public class Pair<F,S>
{
     F first;
     S second;

     public Pair(F first, S second)
     { 
          this.first = first;
          this.second = second;
     }
}

Now instead of having to cast, you simply state:

Pair<Integer, String> pair = new Pair<Integer, String>(10, "Ten");

Upvotes: 1

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

The problem is that plain <V> can't be understood as a Drink but as a generic Object. You need to bind the generic to your Drink class, so declare the generic as <V extends Drink>.

More info: Generic Methods and Bounded Type Parameters

Upvotes: 1

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279990

The compiler decides if method calls are valid based on the type they are called on. You have

public static <V> V go1(V o){
    o.sip();
}

but V is not a bounded type so the compiler can only be sure that it is at least of type Object. Object doesn't have a sip() method. You need to bound your type

public static <V extends Drink> V go1(V o){
    o.sip();
}

This way the compiler knows that V is at least of type Drink. Drink has a sip() method.

Upvotes: 1

Related Questions