views:

177

answers:

3

This is related to final interface in java. Among the discussion there was that the concept of final in relation to interfaces is ambiguous. Would a final interface mean that it can not have subinterfaces? Would it mean that it can not have implementations?

This question is the first: can you write an final interface such that the compiler will prevent you from implementing it?

+2  A: 

I submit the following as an interface such that implementation will be prevented at compile-time.

interface FinalInterface
{
    class Types
    {
        private class Alpha { }

        private class Beta { }
    }

    void method ( Types . Alpha param ) ;

    void method ( Types . Beta param ) ;
}
emory
This is incorrect, as shown in my answer.
Matthew Flaschen
Why answer your own question, and immediately?
Thorbjørn Ravn Andersen
@Thorbjørn Ravn Andersen b/c I was curious if my FinalInterface interface could be implemented.
emory
+1  A: 

Technically, you can, by specifying parameters that are not accessible to implementors - for example in the same package as the interface, with package-private visibility.

But that does not make any sense. This interface is completely useless in this case.

Update: One use comes into my mind, but this should not be done. If you want to use interfaces for constant definitions, in order to spare the bunch of modifier that an interface assumes, but you don't want to use the anti-pattern of implementing a constants-only interface.

Bozho
Interestingly enough, C# prevents such an interface at compile-time, with an "inconsistent accessibility" error.
Jon Skeet
@Jon Skeet - and what happens if the interface is also declared package-private? I guess the error doesn't appear then.
Bozho
@Bozho: Yup (or rather, an internal interface using internal types). On the other hand, when *implementing* that method, you'd have to use explicit interface implementation, because otherwise you'd have to declare the *implementing* method as public, which would result in the same error :(
Jon Skeet
+4  A: 

As I will show, it is possible to implement the interface above using a proxy. The more meaningful question is, why would you try to make a unimplementable interface? Even as a philosophical point, it seems rather shallow.

import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

class NoFinal
{
    public static void main(String[] a) throws Throwable
    {
        FinalInterface o = (FinalInterface) Proxy.newProxyInstance(FinalInterface.class.getClassLoader(), new Class[]{FinalInterface.class}, new InvocationHandler()
        {
            public Object invoke(Object proxy, Method method, Object[] args)
            {
                System.out.println(method);
                return null;
            }
        });
        Method[] methods = FinalInterface.class.getDeclaredMethods();
        methods[0].invoke(o, new Object[]{null});
        methods[1].invoke(o, new Object[]{null});
    }
}

This won't give an error at compile or run-time, and it shows you can make a real instance of this interface with both methods callable.

Matthew Flaschen
I see using reflection it is possible to implement any interface. Good One.
emory