简体   繁体   中英

How to call a method of a parameterized type?

Just jumping into Java Generics and I've run into a bit of a problem: I can't seem to invoke the method of a parameterized type:

class test 
{
    public static void main( String args[ ] )
    {    
        invoke_baz( new foo( ) );
    }
    public static < Type > void invoke_baz( Type object )
    {
        object.baz( );
    }   
    public static class foo
    {
        public void baz( )
        {   }
    }       
}

What am I missing here?

You've declared your generic type parameter Type , but it could be anything, not just a foo , such as a String .

Restrict type with an upper bound so that you know it's some kind of foo :

public static <Type extends foo> void invoke_baz( Type object )

Alternatively, just ask for a foo in your argument, removing any need for generics:

public static void invoke_baz(Foo object)

Java is not duck typed, the type checker is not able to realize that the generic method is calling a method that is available on the object you are then passing to the method. It must correctly check that generic code regardless of your specific case.

You need to fullfil this by explicitly declaring the type variable is restricted to a certain hierarchy of classes so that the type checker can make assumptions on it:

interface Bazzable {
  public void baz();
}

public <Type extends Bazzable> void invoke(Type object) {
  object.baz();
}

public class Foo implements Bazzable {
  public void baz() {
    System.out.println("baz");
  }
}

In this way you specify that the type variable is at least a Bazzable so you will be restricted to pass only certain types to the method but on the other side you will be able to call any method that is specified in Bazzable .

You can't because it's a generic -- type type isn't known at compile time. Compiler didn't know what the type was -- nor do you. One approach is to do a runtime cast. You first need to decide what type you'd expect, and you can do something like this:

public static < Type > void invoke_baz( Type object )
{
    SomeClass someClass = (SomeClass) object;
    someClass.baz();
}  

This would ofcourse produce cast error if provided object / type isn't of type SomeClass .

Better approach would be to declare an interface that ensure contracts of your method, eg:

public interface HaveBaz {
  baz();
}

And request subtype of that interface on your generic method declaration

public static < Type extends HaveBaz > void invoke_baz( Type object )
{
  object.baz();
}  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM