10

Right now I the following:

1) A java interface.

2) A concrete java class that does not implement the aforementioned interface, but does contain a method signature matching every one of the methods defined in the interface.

Since I am unable to change the implementation of item 2, I would like to know if it is possible to make a method that accepts an instance of item 1 as an argument accept item 2 without a class cast exception.

It feels like the various weaving/coercion/AOP mechanics in Spring should make this possible, but I don't know how to do it.

Is there a way to make this happen?

2
  • 2
    Can't you just make a wrapper that implements the interface and forwards everything? Commented Mar 4, 2011 at 17:13
  • Does anyone know if there is a name for this pattern (what OP wants) where you are 'casting' an object with matching signature onto an interface? Commented Apr 11, 2017 at 11:57

5 Answers 5

9

Can you force a java object into implementing an interface at runtime?

Yes, using dynamic proxies or byte-code rewriting. However, to me it seems like you're looking for the Adapter pattern.

Sign up to request clarification or add additional context in comments.

3 Comments

Do you have links to any documentation on how to do that, preferably declaratively?
@dskiles, Using proxies, see Java Dynamic Proxy - How reference concrete class. For an AoP approach have a look at the aspectj or cglib projects .
The adapter pattern is the way to go, but it's a little insane that a language requires an object to explicitly implement all of the interfaces it will satisfy. Implicit interfaces are definitely the way to go, but that's no help to Java programmers.
4

You can't make the object itself implement the interface, but you could use something like Proxy to create an object which implements the interface and uses reflection to call the appropriate member on the original object.

Of course, if it's just the one interface type and the one concrete type, you could easily write such a wrapper without using Proxy:

public class BarWrapper implements Foo
{
    private final Bar bar;

    public BarWrapper(Bar bar)
    {
        this.bar = bar;
    }

    public int someMethodInFoo()
    {
        return bar.someMethodInFoo();
    }

    // etc
}

Comments

2

This should be solvable with an adapter. Have an other class defined that implements your interface and delegates to the real object:

class YourAdapter implements YourInterface {

    private final YourClass realObject;

    public YourAdapter(YourClass realObject) {
        this.realObject = realObject;
    }

    @Override
    public methodFromInterface() {
        // you said the class has the same method signatures although it doesn't
        // implement the interface, so this should work fine:
        realObject.methodFromInterface();
    }

    // .......

}

Now, given a method that expects YourInterface and an object of type YourClass:

void someMethod(YourInterface param) {}

void test() {
    YourClass object = getFromSomewhere();
    someMethod( YourAdapter(object) );
}

2 Comments

That's what I have in place now, but I was hoping to skip the adapter step, if possible.
Then you will need to go with the Proxy approach mentioned in some of the other answers, if you don't mind reflection.
0

You can probably do what you want with Javassist, either by modifying the class's bytecode or creating a wrapper/proxy class.

Comments

0

Basically there are two ways:

a) write a decorator around your Object that implements the interface and delegates to your object (this can be done either by using proxies or by writing a simple adapter class)

b) change the byte code. Spring AOP is not powerful enough to do that, but the AspectJ compiler is. It's a one-liner:

declare parents: YourClass implements YourInterface;

Since you don't have access to the class source you will have to either use Load Time Weaving or weave the library jar. All of this is explained well in AspectJ in Action by Ramnivas Laddad

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.