Abstract callback in reflection method of java - java

I have a class in jar of which I want to invoke a method. But that method has parameter of abstract class and that abstract class is inner method of class in jar. AbstractClassA is a HIDDEN class. Here is code:
public class A{
private invokeThisMethod(AbstractClassA object){
}
public abstract class AbstractClassA {
public void update(int remaining){}
}
}
public class myClass{
//using Reflection get object of class A
objectOfClassAusingReflection.inovke("invokeThisMethod", params)
}
Problem here is how do I create concrete implementation of AbstractClassA to pass in invoke method and get update method callbacks ?

Something like this should work:
AbstractClassA a = new AbstractClassA() {
public void update(int remaining) {... do something...}
};
objectOfClassAusingReflection.inovke("invokeThisMethod", a);

You cannot create an instance of abstract class or any interface at runtime.
Instead create an anonymous class for this.
public abstract class A {
public void fun(){....}
public abstract void absFun();
}
public class MyClass {
objectOfClassA = new A(){
public void absFun(){...}
}
}
Or you can first create implementation for that abstract classes for which you will have to create another class extending A
class AWrapper extends A {
public class ImplementationClassA extends AbstractClassA {
// override abstract functions...
}
}
Now you can use this Awrapper class
AWrapper wrapperObj = new AWrapper();
A obj = wrapperObj; // just to make it clear that A can hold wrapperObj as it is implementation of it.
A.AbstractClassA absObj = wrapperObj.new ImplementationClassA();
...
objectOfClassAusingReflection.inovke("invokeThisMethod", params)

Below code should work--
Here, i used anonymus classes for both outer and inner class and then with the help of getdeclatedMethod called your update method.
"TestAbs" is your jar class--
public abstract class TestAbs {
private void invokeThisMethod(AbstractClassA object) {
}
public abstract class AbstractClassA {
public void update(int remaining) {
}
}
}
Then calling your jar class from "TestAbs1" like below--
public class TestAbs1 {
public static void main(String[] args) {
TestAbs.AbstractClassA abs = new TestAbs() {
AbstractClassA a = new AbstractClassA() {
public void update(int remaining) {
System.out.println("Inside update method : " + remaining);
}
};
}.a;
try {
int i = 1;
Class<?> class1 = Class.forName("app.test.mytest.TestAbs$AbstractClassA"); -- (*Getting instance of inner class*)
System.out.println(class1.getDeclaredMethod("update", int.class));
class1.getDeclaredMethod("update", int.class).invoke(abs, i);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The output i got is --
public void app.test.mytest.TestAbs$AbstractClassA.update(int)
Inside update method : 1
Answer to your Comment:-
What I understood from your comment is that, you wanted to call method from abstractClass which is hidden in outerclass.
As per my understanding, there is one way like below--
public abstract class TestAbs {
private void invokeThisMethod(AbstractClassA object) {
}
private abstract class AbstractClassA { --- your hidden class
public void update(int remaining) {
}
}
public class ImplementedClass extends AbstractClassA{ -- use implemented class here
....
...
}
}
And after that, use your ImplementedClass the same way mentioned above.
You can find reference example for private inner class here from java docs.
Note: In your question context, since your inner class and outer class is in jar, so I think it is difficult for you add implementation class in your jar.
In case, you find any alternatives, please let all knows about this;
thanks.

Related

Why an anonymous class can't implement two separated interfaces but can implement inner interfaces?

An anonymous class can extend only from one class or interface, so I can't do the next :
interface Enjoyable {
public void enjoy();
}
interface Exercisable {
public void exercise();
}
public class Test {
public static void main(String[] args) {
new Enjoyable implements Exercisable() {
public void enjoy() {
System.out.println(":D");
}
}.enjoy();
}
}
It says that :
Enjoyable.Exercisable cannot be resolved to a type
I'm trying to replicate this behavior and I wrote the next code:
interface Enjoyable {
interface Exercisable {
public void exercise();
}
public void enjoy();
}
public class Test {
public static void main(String[] args) {
new Enjoyable.Exercisable() {
public void enjoy() {
System.out.println(":D");
}
public void exercise() {
System.out.println("Doing exercise !!!");
}
}.exercise();
new Enjoyable.Exercisable() {
public void enjoy() {
System.out.println(":D");
}
public void exercise() {
System.out.println("Doing exercise !!!");
}
}.enjoy();
}
}
And then I get :
Doing exercise !!! :D
Are there another way to simulate It?
And way i hace to implement both metods un the anonymous class ?
Thanks
I want an anonymous class who implements 2 interfaces methods
I assume you mean you want an anonymous class which implements two interfaces. You can't, directly.
You can do
interface EnjoyableAndExercisable extends Enjoyable, Exercisable {
}
and then create an anonymous class that implements that.
EnjoyableAndExercisable o = new EnjoyableAndExercisable() {
#Override
public void enjoy() {
System.out.println(":D");
}
#Override
public void exercise() {
System.out.println("Doing exercise !!!");
}
};
Note the #Override which will always validate whether you are actually overriding a method or not.
In your code however, this anonymous class
new Enjoyable.Exercisable() {
public void enjoy() {
System.out.println(":D");
}
public void exercise() {
System.out.println("Doing exercise !!!");
}
}.enjoy();
is only an implementation of Exercisable. You just happen to declare a method with the name enjoy within it.
You cannot assign it to a variable of type Enjoyable
Enjoyable ref = new Enjoyable.Exercisable() {
public void enjoy() {
System.out.println(":D");
}
public void exercise() {
System.out.println("Doing exercise !!!");
}
}; // nope, compile time error
You can only invoke that method on the new instance creation expression that declares this anonymous type. You cannot invoke it any other way (since it's declared in an anonymous type).
your Exercisable's are not Enjoyable :-)
nesting interfaces this way does not mean that the inner interface is
of the type of the outer interface !
you could just as well have written something like
new Object() {
public void enjoy() {
System.out.println(":D");
}
public void exercise() {
System.out.println("Doing exercise !!!");
}
}.enjoy()
// same for .excercise()
so you are not actually simulating an anonymous class that implements two interfaces.
you can see this when you actually try to assign your anonymous instance to a variable of a type of your interfaces
// this WILL NOT COMPILE !
Enjoyable enjoyable=new Enjoyable.Exercisable() {
public void enjoy() {
System.out.println(":D");
}
public void exercise() {
System.out.println("Doing exercise !!!");
}
}.enjoy();
you could of course do something like this :
interface Enjoyable {
public void enjoy();
}
interface Exercisable extends Enjoyable {
public void exercise();
}
and then create anonymous instances using those interfaces
Unfortunately creating an anonymous instance that implements two interfaces like you are trying to do is not possible.
You can create anonymous inner classes based on a non-final class or an interface with
new Exerciseable(){
...
}
However, Java does not allow
new Object() implements Exercisable{
...
}
or
new Object implements Exercisable(){
...
}
The anonymous inner class produces with the new keyword a new instance of a class whose superclass is Object and implements Exercisable. The JCP site hosts a document (https://jcp.org/aboutJava/communityprocess/maintenance/JLS/innerclasses.pdf), belonging to the JSL about inner classes which says:
As already hinted, if an anonymous class is derived from an interface
I, the actual superclass is Object, and the class implements I rather
than extending it. (Explicit implements clauses are illegal.) This is
the only way an interface name can legally follow the keyword new. In
such cases, the argument list must always be null, to match the
constructor of the actual superclass, Object.
Your second example constructs a type Exercisable which extends Enjoyable. Creating anonymous classes of that interface is legal again.

Identifying the child class calling a base class static function

Suppose I have a base class with a function foo
public class Base
{
protected static void foo()
{
// ToDo - what is the name of the child class calling me?
}
}
and at least one child class containing a static initialiser that calls foo
public class Child extends Base
{
static
{
foo();
}
}
Is there a way of foo() knowing which child class has called it? I'm presuming there's a reflection technique I can use.
The simplest way is to pass an argument. For example
public class Base {
protected static void foo(Class<?> type) {
if (type == Child.class) {
}
}
}
public class Child extends Base {
static {
foo(Child.class);
}
}
However, if you need to do something that depends on the child class then I recommend looking for a solution that leverages abstract methods and polymorphism.
public Base {
protected static void foo(Base child) {
child.doFoo();
}
protected abstract void doFoo();
}
public Child extends Base {
static {
foo(new Child());
}
#Override
protected void doFoo() {
//do the child specific thing here
}
}
You can get the class by using the getClass method, like:
o.getClass()
also, if you have a class c and you need to check whether o is an instance of c, you can use instanceof, like this:
o instanceof c
Cheers.

Calling a method of sub-sub-class

I am having issue with calling a method of a class at the 2nd level of inheritance from the super class.
The scenario is this,
abstract class SuperClass
{
public void MethodOne()
{
MethodTwo();
}
public abstract void MethodTwo();
}
class Sub1 extends SuperClass
{
public void MethodTwo()
{
//code in sub1
}
}
class Sub2 extends SuperClass
{
public void MethodTwo()
{
//code in sub2
}
}
With the below code I expect the MethodTwo() from the Sub2 to be called. But the method from Sub1 is getting called. Am I missing something?
SuperClass anObj = new Sub2();
anObj.MethodOne();
I have combined all of your classes as inner-classes to help me test them. You can remove the "static" keyword from the classes if you put them in different files:
public class Example {
abstract static class SuperClass
{
public void MethodOne()
{
MethodTwo();
}
public abstract void MethodTwo();
}
static class Sub1 extends SuperClass
{
#Override
public void MethodTwo()
{
System.out.println("Sub1.MethodTwo()");
}
}
static class Sub2 extends SuperClass
{
#Override
public void MethodTwo()
{
System.out.println("Sub2.MethodTwo()");
}
}
public static void main(String[] args) {
SuperClass anObj = new Sub2();
anObj.MethodOne();
}
}
When I run this class it outputs Sub2.MethodTwo(), proving that it does actually work as you expect.
I notice the code you provided is not proper java code, and does not compile. That's because you've marked methods both as abstract and then provided an implementation with curly-braces { ... }.
I assume this is an example of a setup that isn't working for you? If so, I think it doesn't represent your case properly - as it's working as one would expect!
First, you lack the actual implementation of method2.
You should not be able to call an abstract method.
You need to override the abstract in the subclass.
class Sub1 extends SuperClass
{
#override
public void MethodTwo()
{
//code in sub1
}
}
class Sub2 extends SuperClass
{
#override
public void MethodTwo()
{
//code in sub2
}
}
This might fix your problem.

Overwriting methods: how to "inject" into the super-method?

Assuming three classes, one being a subclass of the other. Each overwrite the parents' method.
public class BaseClass {
public void doStuff() {
performBaseTasks();
}
}
public class MiddleClass extends BaseClass {
// {BaseClass} Overrides
public void doStuff() {
performMiddleTasks();
super.doStuff();
}
}
public class FinalClass extends MiddleClass {
// {BaseClass} Overrides
public void doStuff() {
performFinalTasks();
super.doStuff();
}
}
When calling new FinalClass().doStuff(), this would lead to a method
invokation order as follows:
performFinalTasks();
performMiddleTasks();
performBaseTasks();
I want to bring the perfomFinalTasks() between performMiddleTasks() and
performBaseTasks(). How can I do this?
performMiddleTasks();
performFinalTasks();
performBaseTasks();
Write a public method in final class doStuffDifferently() and invoke these methods in that order. I am not sure it's possible to do it via any other tricks in the doStuff() method.
One possible way, if you can make the middle class abstract:
public abstract class MiddleClass extends BaseClass {
// {BaseClass} Overrides
public void doStuff() {
performMiddleTasks();
doProxyExec();
super.doStuff();
}
public abstract void doProxyExec();
}
You override the proxy method in your subclass:
public class FinalClass extends MiddleClass {
// {BaseClass} Overrides
public void doStuff() {
super.doStuff();
}
// {MiddleClass} Overrides
public void doProxyExec(
performFinalTasks();
}
}
A not very polymorphic way of method call chaining, but then again the original design is kind of ... odd.

Super class which uses the values from children

I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}

Categories