Generic Anonymous Inner Class Instantiation - java

I'm reading up on WebSocket Endpoints in Java EE and I came accross this
public class EchoEndpoint extends Endpoint {
#Override
public void onOpen(final Session session, EndpointConfig config) {
session.addMessageHandler(new MessageHandler.Whole<String>() {
#Override
public void onMessage(String msg) {
try {
session.getBasicRemote().sendText(msg);
} catch (IOException e) { ... }
}
});
}
}
This part,
new MessageHandler.Whole<String>() {....
Is Whole a generic Inner class? And since we are specifying String as a type parameter, onMessage accepts Strings? This looks really weird to me, we could just subclass Whole, and Override onMessage and that would be a different class. Then we could pass that with the type parameter to addMessageHandler right? But here, we are just overriding it and specifying the type parameter at the same time here right?
EDIT
So I have learned MessageHandler is an interface with two nested interfaces in it
MessageHandler.Whole<T> and
MessageHandler.Partial<T>
Now we pass an object of the type MessageHandler into the method addMessageHandler, how could it know that this object implements the onMessage method. It's not supposed to know, because this method is in the nested interface Whole.

Is Whole a generic Inner class?
No. It's a generic nested class (interface, to be precise), as the javadoc shows. The term "inner" is for non-static nested classes, which implicitly have a reference to an instance of their owning class. See the tutorial.
And since we are specifying String as a type parameter, onMessage accepts Strings?
Correct, as the javadoc shows.
we could just subclass Whole, and Override onMessage and that would be a different class
That's exactly what this code is doing. It creates and instantiates an anonymous subclass os Whole.
Now we pass an object of the type MessageHandler into the method addMessageHandler, how could it know that this object implements the onMessage method. It's not supposed to know, because this method is in the nested interface Whole.
As the javadoc shows, the interface Whole extands the interface MessageHandler. That's why you can pass a Whole to a method which expects a MessageHandler (just like you could pass a Banana to a method expecting a Fruit, because Banana is a Fruit).

Related

Java polymorphism through injection at runtime

I hear that in Java I can achieve polymorphism through injection at runtime. Can someone please show a simple example of how that is done? I search online but I can't find anything: maybe I am searching wrong. So I know about polymorphism through interface and and extension such as
class MyClass extends Parent implements Naming
in such case I am achieving polymorphism twice: MyClass is at once of type Parent and Naming. But I don't get how injection works. The idea is that I would not be using the #Override keyword during injection. I hope the question is clear. Thanks.
So the end result here, per my understanding, is to change the behavior of a method through injection instead of by #Override it during development.
So I know about polymorphism through interface and and extension such as
class MyClass extends Parent implements Naming
This is known as inhertiance and not polymorphism. MyClassis a Parent and MyClass is also a Naming. That being said, inheritance allows you to achive polymorphism.
Consider a class other thanMyClass that also implements Naming :
class SomeOtherClass implements Naming {
#Override
public void someMethodDefinedInTheInterface() {
}
}
Now consider a method that takes a Naming argument somewhere in your code base :
public void doSomething(Naming naming) {
naming.someMethodDefinedInTheInterface();
}
The doSomething method can be passed an instance of any class that implements Naming. So both the following calls are valid :
doSomething(new MyClass());//1
doSomething(new SomeOtherClass());//2
Observe how you can call doSomething with different parameters. At runtime, the first call will call someMethodDefinedInTheInterface from MyClass and the second call will call someMethodDefinedInTheInterface from SomeOtherClass. This is known as runtime-polymorphism which can be achieved through inheritance.
But I don't get how injection works. The idea is that I would not be using the #Override keyword during injection
That's true in the broader sense. To inject something into a class, the class should ideally favor composition over inheritance. See this answer that does a good job in explaining the reason for favoring composition over inheritance.
To extend the above example from my answer, let's modify the doSomething method as follows :
public class ClassHasANaming {
private Naming naming;
public ClassHasANaming(Naming naming) {
this.naming = naming;
}
public void doSomething() {
naming.someMethodDefinedInTheInterface();
}
}
Observe how ClassHasANaming now has-a Naming dependency that can be injected from the outside world :
ClassHasANaming callMyClass = new ClassHasANaming(new MyClass());
callMyClass.doSomething();
If you use the Factory pattern, you can actually chose which subclass gets instantiated at runtime.
Do you think we could have done what we did above using inheritance?
public class ClassIsANaming implements Naming {
public void doSomething() {
someMethodDefinedInTheInterface();
}
#Override
public void someMethodDefinedInTheInterface() {
//....
}
}
The answer is No. ClassIsANaming is bound to a single implementation of the someMethodDefinedInTheInterface method at compile time itself.
`
Taking a contrived example. You have a class Store that stores things:
class Store {
private List l
void store(Object o) {
l.add(o);
}
void setStoreProvider(List l) {
this.l = l
}
}
You can inject the actual List used as the backing storage using setStoreProvider which could be a linked list, array backed list, whatever.
Hence, depending on the injected type your Store class would have the features of the injected type (with regards to memory usage, speed, etc).
This is a kind of polymorphism without the class implementing an interface.

What kind of Object are you creating when you create a Path using the Paths.get(String) method?

Obviously since Path is an interface it cannot be instantiated by using the new keyword and so we use Path.get() to create a path from a string. But what kind of object is this, it can't be a path object can it because Path is an interface, but when I call the .getClass().getCanonicalName() method I get some cryptic "sun.nio.fs.WindowsPath" response which doesn't answer anything since I can't instantiate this either
edit : after playing around with the runnable interface I found it is quite easy to use a method to create an implementation of an interface and therefore I would like to clarify my question somewhat. When you create an instance of an object that extends an interface you are creating an instance of that object e.g. An object from class Bar is a Bar object even if it extends the interface Foo. But say I write an implementation for an Interface Foo without writing a class that extends it ; my question is what kind of object is this?
public Interface Foo { public void doStuff();}
Then in main:
Foo foo1 = new Foo(){
public void doStuff(){
// code goes here
}
};
What kind of object is foo1?
The Path is obtained by invoking the getPath method of the default FileSystem.
See also http://docs.oracle.com/javase/7/docs/api/java/nio/file/FileSystems.html#getDefault%28%29

How to force putting a object into a handler class

I already post some relevant code in this question:
Specify object type of a returned array list dynamically
Now my question is a little bit more specific.
In fact I am using the following "handler" class to invoke methods of classes which implement the interface IMSSQLStatement:
public class MSSQLHandler {
IMSSQLStatement statement;
public MSSQLHandler(IMSSQLStatement statement) {
this.statement = statement;
}
public void invoke() throws SQLException {
statement.executeStatement();
}
public List<?> getDataList() throws SQLException {
return statement.getDataList();
}
}
The question is now how to force me (or an developer which implements my interface) to put created objects of the implemented class to MSSQLHandler?
Maybe this is bad design but I did not find any information and use cases regarding my problem.
Yes, you can use an abstract class with an explicit constructor, that is automatically called on all subclasses:
public abstract class IMSSQLStatement {
protected IMSSQLHandler handler;
public IMSSQLStatement() {
handler = new IMSSQLHandler(this);
}
}
Edit: (in reference to comment)
If you want that only the handler should be able to call the methods in IMSSQLStatement, both classes should be placed in the same package. Allow only package-private and subclass access, by giving the protected modifier. Although the methods could be called in the subclass itself, it would not be accessible outside, with the exception of the package.
This won't solve your problem completely. The other (real bogus) way around would be reflection.
To use reflection, you should write in your documentation the exact method signature the subclass should use (of course, don't define an abstract method in the superclass), giving it the private modifier. The handler should access these methods through reflection.
Refer some document, that describes how to use reflection. This is complicated, and beyond the scope of SO.

How to find the first declaring method for a reference method

Suppose you have a generic interface and an implementation:
public interface MyInterface<T> {
void foo(T param);
}
public class MyImplementation<T> implements MyInterface<T> {
void foo(T param) {
}
}
These two types are framework types I provide. In the next step I want allow users to extend that interface as well as redeclare foo(T param) to maybe equip it with further annotations.
public interface MyExtendedInterface extends MyInterface<Bar> {
#Override
void foo(Bar param);
// Further declared methods
}
I create an AOP proxy for the extended interface and intercept especially the calls to furtherly declared methods. As foo(…) is now redeclared in MyExtendedInterface I cannot execute it by simply invoking MethodInvocation.proceed() as the instance of MyImplementation only implements MyInterface.foo(…) and not MyExtendedInterface.foo(…).
So is there a way to get access to the method that declared a method initially? Regarding this example is there a way to find out that foo(Bar param) was declared in MyInterface originally and get access to the accoriding Method instance?
I already tried to scan base class methods to match by name and parameter types but that doesn't work out as generics pop in and MyImplementation.getMethod("foo", Bar.class) obviously throws a NoSuchMethodException. I already know that MyExtendedInterface types MyInterface to Bar. So If I could create some kind of "typed view" on MyImplementation my math algorithm could work out actually.
Additional info:
I create the proxy for the MyExtendedInterface as follows:
ProxyFactory factory = new ProxyFactory();
factory.setTarget(new MyImplementation());
factory.setInterfaces(new Class[] { MyExtendedInterface.class });
factory.addInterceptor(new MyInterceptor(MyExtendedInterface.class));
The interceptor pretty much scans the methods and executes JPA queries for all methods declared in MyExtendedInterface but routes all method invocations of methods declared in MyInterface to the proxy target. This works as long as methods from MyInterface are not redeclared as the target then doesn't implement it anymore.
public class MyInterceptor implements MethodInterceptor {
public Object invoke(final MethodInvocation invocation)
throws Throwable {
// handling of query methods
// else
invocation.proceed();
// ^^ works if not redeclared but not if
}
}
So what I would like to do instead of invocation.proceed() is detect the method that originally declared the one being invoked and invoke that on the target manually.
Okay, here's the solution I came up with: As I know the base class and it generics structure (what T means in this case) as well as MyExtendedInterface types MyInterface to Bar I can scan the base implementation for possible matches as follows (pseudocode):
for all methods {
skip those with non matching name and parameters length;
for all generic parametertypes {
if typename = T then concrete type has to be Bar
...
}
}
I don't need a generic solution in this case so that seems to work.
The whole scenario seems strange. You can't apply AOP declared on MyExtendedInterface to MyImplementation, because it does not implement it.
Second, I don't understand why it matters which interface defines a method, since it is the implementation that the method is invoked on.
Apart from that, you can get all the methods declared by a certain class/interface by getDeclaredMethods(). Then you can iterate on them and find something that matches your criteria (name)

Why Object class methods are available in interface?

Following interface and classes are successfully compiled.
Problem is mentioned in the output below :
interface MyInterface{}
class MyClass implements MyInterface{}
class InterDoubt{
static MyInterface mi ;//= new MyClass() ;
public static void main(String[] args){
System.out.println("X") ;
try{
synchronized(mi){
try{
mi.wait(4000) ;
}
catch(InterruptedException ie){
System.out.println("Exception occured at main.") ;
}
}
}
catch(Exception e){
System.out.println("voilla, MyInterface is an interface,\n" +
"then why compiler allows compilation of\n" +
"mi.getClass(), mi.wait().\n" +
"Or how the methods of Object class are available in an interface."
);
}
System.out.println("Y") ;
}
}
output :
X
voilla, MyInterface is an interface,
then why compiler allows compilation of
mi.getClass(), mi.wait().
Or how the methods of Object class are available in an interface.
Y
Edited :-
I am accepting answer from disown, as it's the most explanatory. But after reading the answer, one more issue get's populated :-
"Remember if the interface tries to declare a public instance method declared 'final' in the Object class then it'll result into a compile-time error. For example, 'public final Class getClass()' is a public instance method declared 'final' in the Object class and therefore if an interface tries to declare a method with this signature then the compilation will fail" (Quoted from explanation).
then why the following code is getting successfully compiled :-
interface MyInter{
public void method() ;
}
class MyClass implements MyInter{
public final void method() {
.......
.......
.......
}
}
What you are correctly pointing out as an exception is specified in the Java Language Specification. Interfaces will automatically get all members from the class java.lang.Object added. From here:
The Java Language Specification clearly says that the members of an interface are those which are declared in the interface and those which are inherited from direct super interfaces. If an interface has no direct superinterface then the interface implicitly declares a public abstract member method corresponding to each public instance method declared in the Object class, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by that interface. This is what makes the signatures of the Object methods available to the compiler and the code compiles without any error. Remember if the interface tries to declare a public instance method declared 'final' in the Object class then it'll result into a compile-time error. For example, 'public final Class getClass()' is a public instance method declared 'final' in the Object class and therefore if an interface tries to declare a method with this signature then the compilation will fail.
At run time there should be a real object (or null) behind the reference mi. The real type will implement this interface hence the compiler allows it. At run time any type that implements that interface could be there.
Yes, all Object's methods are available to everything but Primitive value. Interface objects are still objects so they have Object's methods.
The cast (Object)mi will always succeed so why should you be required to provide it?
The Java Language Specification clearly says that the members of an interface are those which are declared in the interface and those which are inherited from direct super interfaces. If an interface has no direct superinterface then the interface implicitly declares a public abstract member method corresponding to each public instance method declared in the Object class, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by that interface.

Categories

Resources