Java reflection derived class - java

This is my scenario "I have a abstract class. There are many derived classed extending this abstract class with the use of annotations. In addition, I have a method of abstract class, that was reflected all notations in one particular derived class".
// Here's a definition of annotation
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface SampleAnnotation {
int sample();
}
public abstract class A {
// Here's a method to reflect all annotations
// in particular derived class like B or C
#Override
public void foo() {
}}
public class B extends A {
#SampleAnnotation (sample = 1)
public void step1() {}
#SampleAnnotation (sample = 2)
public void step2() {}
}
public class C extends A {
#SampleAnnotation (sample = 1)
public void step1() {}
#Sample (stage = 2)
public void step2() {}
}
How can I use java reflection to reflect all the annotations in specific derived class like B or C ?

Perhaps what you have in mind is this Reflections library.
Using Reflections you can query your metadata such as:
get all subtypes of some type
get all types/methods/fields annotated with some annotation, w/o annotation parameters matching
get all resources matching matching a regular expression

It depends:
Do you want to get all method annotations of a concrete class
Do you want to get all method annotations of all concrete classes
The first one can be achieved with a method implementation of foo like this:
public void foo() {
for (Method method : this.getClass().getDeclaredMethods()) {
for (Annotation a : method.getAnnotations()) {
// do something with a
}
}
}
Then you can invoke foo from your concrete class, for instance:
new B().foo();
For the second case you will need to do class path scanning as Peter Lawrey has pointed out.

Related

Trying to avoid code duplication when implementing abstract methods

I have the following abstract class defined here:
#Slf4j
public abstract class PublishMappingService {
#Autowired
private ErpPackageRepository erpPackageRepository;
#Autowired
private PubSubClient pubSubClient;
#Autowired
private RequestInfo requestInfo;
public abstract void publishMappingUpdateEvent(MappingsEntity mappingsEntity);
public abstract void publishMappingUpdateEvent(List<MappingsEntity> mappingsEntityList);
public void publishEvent(String companyId) {
ErpPackage erpPackage;
try {
erpPackage = erpPackageRepository.getSelectedErpPackageForCompanyId(companyId);
pubSubClient.publishEventAsync(
new MappingUpdatedEvent(
erpPackage.getPartnerId(), erpPackage.getCompanyId(),
erpPackage.getErpId(), this.requestInfo.getCorrelationId(),
null
)
);
} catch (NotFoundException e) {
log.error("MappingsRepository::publishEvent: This entity is not registered with ECP - companyId: {}", companyId, e);
} catch (Exception e) {
log.error("MappingsRepository::publishEvent: Failed to publish MappingUpdatedEvent for {}", companyId, e);
}
}
}
Let's say I have two classes (A and B) that inherit from the abstract base class
public class A extends PublishMappingService {
// public class B extends PublishMappingService {
#Override
public void publishMappingUpdateEvent(MappingsEntity mappingsEntity) {
// Identical in Class B
if (mappingsEntity != null) {
String companyId = mappingsEntity.getCompanyId();
publishEvent(companyId);
}
}
#Override
public void publishMappingUpdateEvent(List<MappingsEntity> mappingsEntityList) {
// Identical in Class B
if (mappingsEntityList != null && !mappingsEntityList.isEmpty()) {
String companyId = mappingsEntityList.get(0).getCompanyId();
publishEvent(companyId);
}
}
}
Essentially, the problem is that when I override and implement the abstract methods defined in my subclasses, these methods will be identical across every subclass.
Since I'm not avoiding code duplication with my abstract class, I thought of just making a utility class instead. However, from what I've read, utility classes should only be created if every method can be declared as static which I can't do so as seen in the behavior of the publishEvent method.
I also thought about using an interface with default methods but that approach also wouldn't work since then my instance variables would be need to be static and final, which isn't possible with autowired fields.
Thus, I'm asking to see if there's any alternative ways I can approach refactoring my code to avoid duplication here? Thanks!
If all implementations of an abstract method are identical, then there's no need to have the abstract method in the first place. Move the implementation to the base class.
An abstract method forces all derived classes to implement this method (or be abstract themselves). If child classes are free to implement or override the method, it doesn't have to be abstract.

Creating an intance of a Class via method of an Interface implemented by that class

I want to call the constructor of a class inside the method of an interface.
For example, if I have two classes B and C and they both implement SomeInterface, so that each of them has method foo().
interface SomeInterface {
public SomeInterface foo();
}
class B implements SomeInterface {
public B(int fst, int snd) {}
#Override
public SomeInterface foo() {
return new B(1, 1);
}
}
class C implements SomeInterface {
public C(int fst, int snd) {}
#Override
public SomeInterface foo() {
return new C(1, 1);
}
}
And let's say, for the sake of this question, that I have a lot more classes that implement SomeInterface and they all do the same thing, that is return new <nameoftheclass>(1,1)
and all these classes extend the parent class A.
Is there a way for me to create only one method in A such that if any of these classes use the foo method that is found in A it will call their constructor and just like that save me lines of code?
You can do something like this with reflection, although it will be prone to failure.
public SomeInterface foo() {
Constructor<? extends SomeInterface> c = getClass().getConstructor(int.class, int.class);
return c.newInstance( 1, 1);
}
You'll have to manage some exceptions, but is this what you're after?
The question would then be, where can this be used? Interfaces don't have a common constructor.
public interface SomeInterface{
default SomeInterface another(){
Constructor<? extends SomeInterface> c = getClass().getConstructor(int.class, int.class);
return c.newInstance( 1, 1);
}
}
That would work provided whatever the implementations try to use it have that constructor. There is no guarantee that constructor exists though. Maybe you would want it on an abstract class?
use the foo method that is found in A it will call their constructor and just like that save me lines of code?
You are getting it wrong. Class design decisions must be based on use cases and relationships of the classes in your domain. If your main criteria will be to spare some lines of code, you can end up with a coffee machine extending combine harvester because both of them have tree dimensions. Don't take a pill if you have no headache.
Parent class A that you've mentioned doesn't make any sense because method foo() returns an instance of SomeInterface interface which A doesn't implement (because if it does, its subclasses don't need to declare to implement it). I.e. A and SomeInterface are not compatible and compiler will not allow to type cast between them. Therefore, I'll omit the parent class.
As an example, the "template" you've provided might be useful, will be a situation when classes with similar functionality need to grouped together.
The interface can serve as a single entry point for the user of the code. Every class will implement the behavior defined by the interface, and only through the interface it'll be possible to get an instance of the class with a particular flavor of functionality. The actual classes will be hidden from the user.
Similarly, abstract class NumberFormat from the JDK provides a way to obtain different kinds of formatters, but actual implementations are hidden are not exposed (the approach shown below is far more simple than the actual way of how factory methods of the NumberFormat are implemented).
Note, interface and its implementations must reside in the same package.
public interface BaseInterface {
public static BaseInterface getInstance(Classifier classifier) { // factory
return switch(classifier) {
case A -> new A();
case B -> new B();
};
}
void doSomeThingUseful(); // behaviour that every class should implement
}
enum Classifier { A, B }
class A implements BaseInterface {
A() {}
#Override
public void doSomeThingUseful() {
System.out.println("Class A");
}
}
class B implements BaseInterface {
B() {}
#Override
public void doSomeThingUseful() {
System.out.println("Class B");
}
}
main() - demo
public static void main(String[] args) {
List<BaseInterface> items = List.of(BaseInterface.getInstance(Classifier.A),
BaseInterface.getInstance(Classifier.B));
for (BaseInterface item: items) {
item.doSomeThingUseful();
}
}
Output
Class A
Class B

How do I loop through the interface implementing Classes (and call interface methods of the class) that I have fetched through Refections in Java?

I have tried to fetch a Set of Classes that implements an interface IDispatchIdsReplaceable using Refections. Now what I want to do is loop through these classes, call the interface method (overridden methods) within the loop and perform the implementations. How can I do this?
Pseudo Code:
public interface IDispatchIdsReplaceable {
void replace();
}
public class Class1 implements IDispatchIdsReplaceable {
//usual class methods
#Override
void replace() {
//implementation
}
}
public class Class2 implements IDispatchIdsReplaceable {
//usual class methods
#Override
void replace() {
//implementation
}
}
In some other method, this function is needed
Reflections reflections = new Reflections("com.company");
Set<Class<? extends IDispatchIdsReplaceable>> classesImplementingIDispatchIdsReplaceable = reflections.getSubTypesOf(IDispatchIdsReplaceable.class);
for (Class<? extends IDispatchIdsReplaceable> classImplementingInterface : classesImplementingIDispatchIdsReplaceable) {
//classImplementingInterface.replace(); -> basically somthing like Class1.replace() or Class2.replace() along with the loop.
//How to do the above sort of function call and run those overriden methods of the respective class
}
It gives me error when i run classImplementingInterface.replace() in the loop
Cannot resolve method 'replace' in 'Class'
What is missing here is that replace method should be called from an instance, so you need first to create an instance of that class and then call replace:
for (Class<? extends IDispatchIdsReplaceable> classImplementingInterface : classesImplementingIDispatchIdsReplaceable) {
IDispatchIdsReplaceable instance = classImplementingInterface.getConstructor().newInstance(); // Choose the right constructor, here I'm using the default one
instance.replace();
}
EDIT:
The default constructor should be implemented explicitly inside your subclasses or you will get NoSuchMethodException

Implementing and extending, Interface and Abstract class respectively with same method name in java

I am trying to understand how default methods deal with diamond problem in various scenarios. And, this is one of the scenario which I'm not able to understand.
Following is the description,
1. Interface with a default method method()
2. Abstract Class with a method method()
3. Concrete Class implementing the above interface and extending the abstract class.
interface Interface {
default void method() {
System.out.println("Interface method");
}
}
abstract class AbstractClass {
void method() {
System.out.println("Abstract class method");
}
}
// Concrete class definition first starts
public class ConcreteClass extends AbstractClass implements Interface {
#Override
public void method() {
super.method();
}
public static void main(String[] args) {
Interface test = new ConcreteClass();
test.method();
}
}
// Concrete class definition first ends
// Concrete class definition Second starts
public class ConcreteClass extends AbstractClass implements Interface {
public static void main(String[] args) {
Interface test = new ConcreteClass();
test.method();
}
}
// Concrete class definition Second ends
My queries,
1. Why does definition first always gives output as "Abstract class method" even when I use the Interface type for concrete class object?
2. Why definition second doesn't compile?
If compiler is using abstract class implementation in definition first, then it should be able to identify that it will always use Abstract class implementation in definition second.
This behavior is very confusing to me and any help is greatly appreciated.
Otherwise, the more I delve deeper into this, the more confusing it gets.
Edit 1 :
Compilation error in second definition is "The inherited method AbstractClass.method() cannot hide the public abstract method in Interface"
Default methods are just that: defaults. If there is an implementation, it will be used. If there isn't, the default will be used. There is no diamond problem here (there can be with multiple defaults, however).
1) Dynamic dispatch
2) The abstract class gives the method named method package-private access; the interface demands it be public.

Pointcut for all methods of a class including inherited ones

I am playing around with aop and aspectj and discovered an (for me) unexpected behavior.
In the aspectj-docs I found the following example-pointcut:
execution(public void Middle.*())
for the following class-definitions (I slightly changed the original example):
class Super {
public void m() { ... }
}
class Middle extends Super {
}
class Sub extends Middle {
#Override
public void m() { ... }
}
The description of that exmaple states:
[The pointcut] picks out all method executions for public methods returning void and having no arguments that are either declared in, or inherited by, Middle, even if those methods are overridden in a subclass of Middle.
This example is working fine for me but if class Sub is not overriding m(), the method-calls from outside to m on a Sub-instance are not intercepted. Doesn't this violates the doc?
I had another problem with pointcuts in inhertied classes which is caused by the use of proxies. But in this case the use of a proxy cannot cause this behavior because the proxy should provide methods for all of the proxied class. Or did I missed something?
my aspect-definition:
#Aspect
public class MyAspect {
#Before(value = "execution(* Middle.*(..))", argNames="joinPoint")
public void myAdvice(JoinPoint joinPoint) {
System.out.println("adviced: " + joinPoint.getSignature());
}
}

Categories

Resources