weima
weima

Reputation: 4912

Java: how to specity a type for a function parameter without specifying a full type

Suppose i have a interface like this,

interface MyIntf{
  void generate();
}

and a method like below

void run(Myintf x) {
  x.generate();
}

I could call run() with an object of a class which implements MyIntf.

but is it possible in Java to declare run without an explicit name for the interface.

i.e. can i specify run() like this?

void run("Some object which has a method called 'void generate()'" x){
  x.generate();
}

and run() can be called with an object of any class which has a method called

void generate();

Upvotes: 1

Views: 113

Answers (7)

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147164

Java uses "nominative" rather than "structural" typing.

Just because a method has the same name and parameters, doesn't mean it does the same thing (put the camera/gun to you head and shoot). If you need to make a legacy type conform to a particular interface, use an adapter. Avoid reflection.

Upvotes: 3

bsimic
bsimic

Reputation: 926

The only way to do this in Java is to either use reflection or use the instanceof operator (which isn't recommended) and then cast the object being passed in to the correct class/interface.

Upvotes: -1

Jesper
Jesper

Reputation: 206916

It is not possible to specify "some object which has a method called void generate()" in Java in the way that you have in mind.

In principle you could do this with reflection: you just pass in an Object and at runtime you check if there is a void generate() method that you can call. This means however that you are throwing away the type safety that the compiler provides; I don't recommend using this solution.

public void run(Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    Method m = obj.getClass().getMethod("generate");
    m.invoke(obj);
}

Upvotes: -1

Marcelo
Marcelo

Reputation: 4608

You could do:

void run(Object x){
    try{
        //use reflection to try and run a generate() method on x
    } catch (Exception e){}
}

but there's no way to enforce that at compile time.

Upvotes: 0

Samurai Girl
Samurai Girl

Reputation: 998

No, you cannot do that. This is exactly what interfaces are for :) Unless you don't use reflection..

Upvotes: 3

Guillaume Polet
Guillaume Polet

Reputation: 47617

You must then use reflection to do what you want. Something like:

void run(Object o) {
    Method m = o.getClass().getMethod("generate", new Class[0]);
    if (m!=null)
        m.invoke(o, new Object[0]);
}

You must also add the necessary try/catch (which I don't know by heart), and I think you can pass null instead of the empty arrays.

Upvotes: 4

Bernd Elkemann
Bernd Elkemann

Reputation: 23560

You mean as if you would do something like this?:

void run(Object x) {
  ((Myintf)x).generate();
}

Upvotes: 0

Related Questions