Java Anonymous Class with Interface - java

I didn't write Java for a long time and need some help with something (maybe) simple.
So I got this Class in which an Interface is declared :
public class test(){
interface Checker(){
public check();
}
public someFunction(List param1, Checker param2){
//[do something here]
}
...
public static void main (...){
someFunction(List param1, new Checker(){
...
//[implementation of interface]
...
});
}
So my problem is, that (and the actual Code works fine)
I really don't get why the method someFunction(); expects a Interface as a parameter
I also don't understand why I can pass an instance of an interface to that function(inmain()). The second argument that I'm passing the someFunction();`, is an instance of an interface, right?
Well, what i was thinking of, is that it actually is some kind of anonymous class and therefore it might be possible.
But as I said, it's been a while since I wrote java code, and I didn't find an answer yet, so I would be really grateful if somebody could explain to me why and how this piece of code is working.

1) Because by definition public someFunction(List param1, Checker param2) expects an object of Checker (see parameter 2)
2) Yes, it is an anonymous class, and an instance of it new Checker() creates an object of the class which is passed.
Hence, the code works.

i really dont get, WHY the method someFunction() expects a Interface as parameter
That's a choice of the developer but using an interface here allows you to use any implementation - and only interfaces allow a sort of muliple inheritance in Java.
i also dont understand WHY i can pass an instance of an interface to that function (in main()). The second argument that i'm passing the someFunction(), is an instance of an interface, right? Well, what i was thinking of, is that it actually is some kind of anonymous Class and therefore it might be possible.
The code you see basically creates an anonymous implementation of the interface and instance of that anonymous class. So your guess is correct here.

I'll assume public check() was a typo.
i really dont get, WHY the method someFunction() expects a Interface as parameter
Why not? Your interface is Checker and your method signature is
public someFunction(List param1, Checker param2)
The second argument takes a Checker.
i also dont understand WHY i can pass an instance of an interface to that function (in main()).
You aren't passing an instance of an interface. You are passing an anonymous class. When you say:
new Checker(){
...
//[implementation of interface]
...
});
you are implementing the interface.

Related

Confusion on Polymorphism java

I was reading up on Polymorphism and after some searching I was confused about about the difference of compile-time and run-time polymorphism.
Lets say i have a class ABC and one other class that extends ABC,
class DEF like so:
class ABC{
public void myMethod(){
System.out.println("Overridden Method");
}
}
public class DEF extends ABC{
public void myMethod(){
System.out.println("Overriding Method");
}
}
public static void main(String args[]){
ABC obj = new DEF();
obj.myMethod();
}
}
If we want to be able to replace a class with another class, which performs the same task but in a different way without having too recompile the class that calls them, Is method overriding the way or method overloading?
I guess you are asking two things
1) I was reading up on Polymorphism and after some searching I was
confused about about the difference of compile-time and run-time
polymorphism.
Let's separate the waters here a little bit...
At compile time the compilator validates and transform the code into bytecodes. The static methods calls are resolved during this phase so you know every time the static method is invoked the same and sole implementation will take place.
run-time polymorphism is what happen at execution to decide what actual implementation of a given method to chosse. Considering that each class in the hierchary provides one implementation of this "polymorphic" method. Behind the curtains the compiler do a lot of work to archieve this, using something known as late binding mechanism.
2) If we want to be able to replace a class with another class, which
performs the same task but in a different way without having to
recompile the class that calls them, Is method overriding the way or
method overloading?
You don't actually say that replaces, inteads talks about extends, that is the thing that your are doing when a class extends another. And the implementations of the a method in parent class can be overwritten in a subclass.
Overload, has nothing to do with hierarchies, is to write the same method with diferents set of parameters.
Overloading is when you create multiple classes with the same method name, but different params. If a subclass has the exact same method name and params, it really ends up being overwriting, whether your put #overwrite on top or not. It´s literally the same exact thing and either way you change the outcome of the method, even if you use the base/super - class as a type.
This could be helpful When do you use Java's #Override annotation and why?
You´ll make your compiler complain that you are not actually overwriting a function if you mistype one of the two and nothing ends up being overwritten and you´ll make your code easier to read. It won´t affect the outcome, but you still should use it for those reasons.

Naming methods to generic arguments

I am going over some code and I am adding some interfaces so i can make sure all the classes follow the same basic guidelines.
Now I have an interface called Uni < T > which takes exactly one generic argument.
Say I have a class which implements Uni< Foo > then I would like that class to have this method public foo getFoo(){};
Is there any way to add this method to the interface? I would prefer if i could do something like this in my interface public T getT(); and the second T gets replaced by the generic argument.
I can't just call it "get" because I would like some classes to implement multiple versions of Uni. public Example implements Uni<Foo1>,Uni<Foo2>
I know I can give the function 'get' an argument Foo or Class but I'd rather not so I thought I'd ask here.
(I would also mess up the naming convection if i did this)
No, not possible. And as generics in Java are implemented via erasure (i.e. dropped by the compiler), you will also not be able to implement multiple versions in a single class.
its not possible with java but you can do it like this
public interface example<T> {
public void yourmethod(T object);
}
make the interface according to the generic type you want.

Class and Generic in Java

There is this function
Transformers.aliasToBean(RoomInfoDTO.class);
Now I would to use the above function in my generic method. How do I pass the class into the method and use it ?
I tried the following but it doesn't work
passThis(PurchaseHistoryDTO.class);
....
function passThis(Class<?> passedClass){
Transformers.aliasToBean(passedClass.getClass());
}
Somehow the function takes the class as class java.lang.Class.
Just pass the argument directly without calling getClass on it. passedClass is a Class object, so calling getClass on it will obviously return java.lang.Class. Just do:
function passThis(Class<?> passedClass){
Transformers.aliasToBean(passedClass); //just pass the class, not the class's class
}
Also, I'm assuming that "function" is shorthand/psuedocode; that won't compile in java. substitute it with a return type, probably void.
As you already passed class object PurchaseHistoryDTO.class in
Class<?> passedClass argument,
just pass "passedClass in the method like :
Transformers.aliasToBean(passedClass);
It should work.
You're passing in the class, so you can operate on it directly.
void passThis(Class<?> passedClass) {
Transformers.aliasToBean(passedClass);
}
You also don't say function in Java. You might be thinking of JavaScript.
On another note, there is basically no point to using a generic class as you have it in your example. Passing in simply (Class passedClass) would work just as well.
So the question is why you went the generics route. It could be you want something more like this:
<T> T passThis(Class<T> passedClass){
return Transformers.aliasToBean(passedClass);
}
Just depends on what you are trying to accomplish.

Concrete Class implements a interface. Typecasted to Interface later. How does JVM recognize the Typecasted instance?

A Concrete class typecasted to interface, does JVM still consider it a instance of concrete class ?
When you create an assignment, the type of the assignment is inferred based on the type given. E.g. MyInterface mi = new MyImplementation(); mi in this case is typed as the interface, but refers to the implementation. The JVM will know that the instance points to an implementation if you do instance of.
Before I answer the specific question, note that implementations of interfaces are can be passed anywhere the interface type is accepted. i.e. if Impl implements Interface, Impl isA interface, so why would you cast to the interface type? It would be completely unnecessary. I have seen situations where you would cast to a specific implementation, but not from implementation to interface, and even those situations are dicey.
I had to verify this with the following code, but no, if you have an interface implementation, and you cast it to the interface, anything that requires the implementation will get a compile time error if you try to pass as the interface. Here is the code
public class Runner {
public static void main(String[] args) {
ExampleImpl impl = new ExampleImpl(); // never do this in real life
// Example impl = new ExampleImpl() <-- do this instead "code to the interface"
Example casted = (Example) impl;
takesExampleImpl(casted); // compile error because takesImpl expects the implementation
takesExampleImpl(impl); // works because impl is an implementation
takesExampleImpl((ExampleImpl)casted); // works because I cast it back to imple
}
public static void takesExampleImpl(ExampleImpl instance){
}
static class ExampleImpl implements Example {
public void testMethod() {
System.out.println("impl");
}
}
}
Example is just a simple interface with one method, code not shown.
Also, note that my code answers the question, it does a lot of things wrong--you wouldn't see code like that in a professional setting (or you shouldn't at least). The point of interfaces is so that you can define the behavior, and just pass in an object that conforms to that behavior. So you would not write a method that accepted an implementation, you would write a method that accepted the interface, to which you could pass anything that provided the implementation. That way you can pass different implementations to the same method as the need might arise.

Uninstantiated Anonymous Classes in Java

It's been about 6 years since I've written Java, so please excuse the rust.
I'm working with a library method that requires that I pass it Class objects. Since I'll have to invoke this method a dynamic number of times, each time with a slightly different Class argument, I wanted to pass it an anonymous class.
However, all the documentation/tutorials I've been able to find so far only talk about instantiating anonymous classes, e.g.:
new className(optional argument list){classBody}
new interfaceName(){classBody}
Can I define an anonymous class without instantiating it? Or, perhaps more clearly, can I create a Class object for an anonymous class?
Unfortunately, there's no way you can dodge the instantiation here. You can make it a no-op, however:
foo((new Object() { ... }).getClass());
Of course, this might not be an option if you have to derive from some class that performs some actions in constructor.
EDIT
Your question also says that you want to call foo "each time with a slightly different Class argument". The above won't do it, because there will still be a single anonymous inner class definition, even if you put the new-expression in a loop. So it's not really going to buy you anything compared to named class definition. In particular, if you're trying to do it to capture values of some local variables, the new instance of your anonymous class that foo will create using the Class object passed to it will not have them captured.
short answer
you cannot (using only JDK classes)
long answer
give it a try:
public interface Constant {
int value();
}
public static Class<? extends Constant> classBuilder(final int value) {
return new Constant() {
#Override
public int value() {
return value;
}
#Override
public String toString() {
return String.valueOf(value);
}
}.getClass();
}
let's creating two new class "parametric" classes:
Class<? extends Constant> oneClass = createConstantClass(1);
Class<? extends Constant> twoClass = createConstantClass(2);
however you cannot instantiate this classes:
Constant one = oneClass.newInstance(); // <--- throws InstantiationException
Constant two = twoClass.newInstance(); // <--- ditto
it will fail at runtime since there is only one instance for every anonymous class.
However you can build dynamic classes at runtime using bytecode manipulation libraries such ASM. Another approach is using dynamic proxies, but this approach as the drawback that you can proxy only interface methods (so you need a Java interface).
You can only reference an anonymous class ONCE. If you do not instantiate it there, you cannot instantiate it since you do not have a name for it.
Hence I believe that anonymous classes can only be used in conjunction with a "new BaseClass()".
In your situation you would pass a BaseClass object to your method doing the work, and instantiate the anonymous object in the source code when you need the object to pass.
You can't access the Class object of an anonymous class without instatiating it. However, if you only need access to the class, you could define local classes within your method and refer to these using the ClassName.class literal syntax.
You can assume the name of an anonymous class and call Class.forName("mypackage.MyBaseClass$1") to get a handle to an anonymous class. This will give you the first anonymous class defined in your MyBaseClass, so this is a rather fragile way to refer to a class.
I suspect whatever you are trying to do could be done a better way. What are you really trying to achieve? Perhaps we can suggest a way which doesn't require you to pass a Class this way.
You can access the class object of an anonymous class by calling .getClass() on it immediately after creation. But what good would that do?
I think the key is in this part of what you said:
I'm working with a library method that requires that I pass it Class
objects.
Why does it want you to pass it Class objects? What does this library do with the Class objects you pass it? Instantiate objects? But if so, what constructor does it use and how does it decide what arguments to pass? I don't know what library you are using or what it does, but I would guess that it always creates objects using the no-argument constructor. However, that will not work for anonymous classes anyway, since they have no public constructor (and in any case, to instantiate any non-static inner class, a reference to the outer instance must be provided, so there is no no-argument constructor).

Categories

Resources