jdc0589
jdc0589

Reputation: 7018

Dynamic method return types in java

The following code does exactly what I want it to, but I am curious if there is a better way of going about it. This would be so much easier if Interfaces allowed static methods, or if Java methods could be generalized/parameterized to the extent they can in C#.

I would much rather substitute the parameter "Class<TParsedClass> c" for "Class<AbstractClass> c". To me "Class<AbstractClass>" means a class that extends a certain abstract class, but apparently that is wrong because when I use that parameter and use it as I descibed above, I get compiler errors.

public <TData, TParsedClass> TParsedClass convert(TData data, Class<TParsedClass> c)
{
    try 
    {
        return (TParsedClass)c.getMethod("parse", data.getClass()).invoke(c, data);
    } 
    catch(Exception e)
    {
        e.printStackTrace();
        return null;
    }
}

Upvotes: 1

Views: 3761

Answers (3)

Yishai
Yishai

Reputation: 91931

You can define TParsedClass as TParsedClass extends AbstractClass, but the Class object doesn't represent an abstract class, it is a way of referring to the definition of a type via reflection.

Upvotes: 0

jarnbjo
jarnbjo

Reputation: 34323

It's very hard to guess what you "exactly want to do", but I suppose you have some kind of TParsedClass with a static parse method, which populates a new TParsedClass instance with data from a TData instance.

If you think you need some kind of interface marker to indicate which other object a class can parse, why don't you implement the parse method as a non-static method, which populates 'this' with the data from the passed Object?

E.g.

public class A implements Parser<B> {
    public void parse(B b) {
        this.foo = b.foo;
        this.bar = b.bar;
    }
 }

To convert, you would then do something like this:

A a = new A();
a.parse(b);

instead of

A a = A.parse(b);

Upvotes: 0

Alexander Pogrebnyak
Alexander Pogrebnyak

Reputation: 45606

Yes, there is a better way. Use interfaces:

public interface Parser< TData, TParsedClass >
{
    TParsedClass parse( TData data );
}

public class IntParser
    implements Parser< String, Integer >
{
    public Integer parse( String data )
    {
       return Integer.valueOf( data );
    }
}

public <TData, TParsedData> TParsedData convert(
        TData data,
        Parser< TData, TParsedData > parser
    )
{
    return parser.parse( data );
}

Upvotes: 5

Related Questions