Design Approach and Using Reflection to run methods in Java - java

I have a question. I have multiple classes in a package: Let's say package is
com.myPackage.first
And this package has the following classes:
firstGood
secondGood
thirdBad
fourthGood
Each of these classes have a method with the same name but different implementation. So say each have a one particular function called:
public void runMe(){
}
For now I want to come up with a way to given a class name, it'll go inside the class and run that particular method.
So conceptually, my method will look like those:
ArrayList<Class> classList ; // where classList is a list of classes I want to run
public void execute(){
for(Class c : classList){
// Go inside that class, (maybe create an intance of that class) and run the method called run me
}
}
or
public void execute(Class c, String methodToRun){
for(Class c : classList){
// Go inside that class, (maybe create an intance of that class) and run the method called run me
}
}
For now. what I have been able to do is get the name of the classes I want to run the
runMe()
method. So I have been able to come with a way to get the arraylist of classes I want to run. So what I need help with is coming up with a method such that it takes a class name and run the method I want it to. Any help is appreciated. Thanks

I suggest having a look at Class.forName ( ... ) to get the class object, Class.newInstance(); if your classes have a default constructor (or Class.getDeclaredConstructor(...) otherwise) to create a new instance and then Class.getDeclaredMethod( ... ) to find the method and invoke it.
All of this without any regard if your idea is really a good one, since I really didn't quite understand WHY you want to do what you want to do...

interface Me {
void runMe();
}
Then let all classes implement Me.
And have a list of Mes
List<Class<Me>> ...
Then
void test(Class<Me> cl) {
Me me = cl.newInstance();
me.runMe();
}

My adage is always use reflection to solve a problem - now you have two problems. In view of that have you considered a simple pattern like this:
interface Runner {
public void runMe();
}
static abstract class BaseRunner implements Runner {
public BaseRunner() {
// Automagically register all runners in the RunThem class.
RunThem.runners.add(this);
}
}
class FirstGood extends BaseRunner implements Runner {
#Override
public void runMe() {
System.out.println(this.getClass().getSimpleName() + ":runMe");
}
}
class SecondGood extends BaseRunner implements Runner {
#Override
public void runMe() {
System.out.println(this.getClass().getSimpleName() + ":runMe");
}
}
static class RunThem {
static final Set<Runner> runners = new HashSet<>();
static void runThem() {
for (Runner r : runners) {
r.runMe();
}
}
}
public void test() {
Runner f = new FirstGood();
Runner s = new SecondGood();
RunThem.runThem();
}
Here all of your runMe objects extend a base class whose constructor installs the object in a Set held by the class that calls their runMe methods.

inline
void execute() throws Exception{
for (Class<?> c : classesList)
{
//If you don't already have an instance then you need one
//note if the method is static no need for any existing instance.
Object obj = Class.forName(c.getName());
// name of the method and list of arguments to pass
Method m = c.getDeclaredMethod(methodName,null);
//method accessibility check
if(!m.isAccessible())
m.setAccessible(true);
//invoke method if method with arguements then pass them as new Object[]{arg0...} instead of null
//if method is static then m.innvoke(null,null)
m.invoke(obj, null);
}
}

I would recommend using an Interface that defines the runMe() method and then have all your classes implement that interface. Then you would have a list of this Interface:
List<MyInterface> classes = new ArrayList<MyInterface>();
Then you could easily iterate over it and invoke "runMe()" on all of them or if you only want to invoke it for instances of a certain class you could do it like this:
public void execute(Class classForWhichToExecute) {
for (MyInterface myInterface : classes) {
if (classForWhichToExecute.isAssignableForm(myInterface)) {
myInterface.runMe();
}
}
}
Of course this wouldn't work if your method is a static method - so adding more information from your side would help.

I would suggest to use an interface with a common method to override in each class. So that any class can be casted to interface and use its method to execute the method.
interface GoodAndBad{
public void runMe();
}
Implemented class
class FirstGood implements GoodAndBad{
#override
public void runMe(){
// Code to be executed
}
}
You can use execute() method as follows
public void execute(List<GoodAndBad> classList){
for(GoodAndBad c : classList){
c.runMe();
// Go inside that class, (maybe create an intance of that class) and
// run the method called run me
}
}
Change the Class to GoodAndBad interface to change the other method too.
This is loosely coupling objects to support favor over composition in Java Object Oriented Design Patterns.
Never use Strings of method names to execute a method at anytime. There are plenty of other cool solutions for that using design patterns.

Related

Execute a function "before each" method of the same class in java

I have several methods in a class that require a boolean to be set to true in order to execute correctly.
I could write the if statement in each method, but it is not convenient if I or someone else wants to ad another method. I or he could forget about the check.
Is there a way in java to execute a method before each other methods (exactly like JUnit does with #BeforeEach ) in a class ?
Edit: Lots of very interesting techniques/answers/concepts proposed. I'll be in touch when I've understood them. Thanks.
Lets make a method turnBooleanTrue() where effectively the boolean is set to true in order for the method to be execute correctly.
Then, you can write up your very own InvocationHandler that would intercept calls to your objects, and then reflectively (using reflection API) invoke first the turnBooleanTrue() method followed by the method to which the call was made.
Will look something like this
public class MyClassInvocationHandler implements InvocationHandler {
// initiate an instance of the class
MyClass myClass = new MyClassImpl();
#Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// look up turnBooleanTrue() method
Method turnBooleanTrue = myClass.getClass().getMethod("turnBooleanTrue");
// invoke the method
turnBooleanTrue.invoke(...); // toggle the boolean
// invoke the method to which the call was made
// pass in instance of class
Object returnObj = method.invoke(myClass, args);
return returnObj;
}
EDIT
Added some lines to have an object of MyClass initialized. You need something to invoke the method on and maintain the state. Changed util to myClass in the code example above.
Considering my use case, it was a bit overkill to use AOP or other concepts. So I basically did a check in each functions.
With AOP, this is how what you need would look:
// wraps around all methods in your class that have a boolean parameter
#Around(value = "#target(*..YourClass) && args(yourBool)", argNames = "jp,yourBool")
Object scheduleRequest(ProceedingJoinPoint jp, boolean yourBool) {
if (yourBool) {
jp.proceed(yourBool);
} else {
throw new RuntimeException("cannot execute this method!");
}
}
This would handle the case that the method take the boolean you say needs evaluation as its (only) parameter. If it comes from a different source, you may need to wire it into the aspect somehow, that depends on your overall design.
I suggest a simple solution by dividing your workflow in four components.
You have an interface you use to execute commands.
You have an interface that defines which commands you can use.
You have one wrapper that analyzes your boolean value.
You have an implementation of the work performing class, that implements the second interface.
Your wrapper initialize the worker.
Your wrapper exposes an action performing command that accepts the executing interface.
if the boolean is true, pass the worker to the executing interface work method.
the executing interfaces work method calls the work function on the command instance interface, the worker.
See it online: https://ideone.com/H6lQO8
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
WorkDistributer wd = new WorkDistributer();
wd.enable();
wd.performAction((w) -> {w.printHello();});
wd.disable();
wd.performAction((w) -> {w.printHello();});
wd.enable();
wd.performAction((w) -> {w.printAnswer();});
wd.disable();
wd.performAction((w) -> {w.printAnswer();});
}
}
class WorkDistributer
{
private boolean enabled = false;
private ActionPerformer worker;
public WorkDistributer() {
this.worker = new Worker();
}
public void enable() {
enabled = true;
}
public void disable() {
enabled = false;
}
public void performAction(ActionCommand command) {
if(this.enabled) {
command.run(this.worker);
}
}
}
class Worker implements ActionPerformer {
public void printHello() {
System.out.println("hello");
}
public void printAnswer() {
System.out.println(21 * 2);
}
}
interface ActionPerformer {
public void printHello();
public void printAnswer();
}
interface ActionCommand {
public void run(ActionPerformer worker);
}

Java inheritance and method resolution order

I've got the following code example:
class p {
public void druckauftrag() {
// ...
drucke();
}
public void drucke() {
System.out.println("B/W-Printer");
}
}
class cp extends p {
public void drucke() {
System.out.println("Color-Printer");
}
}
Calling the following lines:
cp colorprinter = new cp();
cp.druckauftrag();
There is no problem understanding why "cp.druckauftrag();" results in console output "Color-Printer".
But when I call:
p drucker = (p)colorprinter;
drucker.druckauftrag();
I get the same output - why?
Does the typecast overwrite the object "drucker" 's method "drucke" with "drucke" from colorprinter?
Thanks in advance for every explanation.
colorprinter does not stop being an instance of cp when you use the cast operator on it, so its implementation of public void drucke() does not change
What you are expressing with your (p)colorprinter casting is the kind of contract (interface) you expect the object colorprinter to satisfy, which includes a public method with the signature public void drucke(), but not any specific implementation.
And, by the way, this casting is already performed implicitly when you declare drucker of the type p, so (p) is redundant in p drucker = (p)colorprinter;. p drucker = colorprinter; will suffice.
Here you can learn more about typecasting.
Keep in mind that it's best practice to extend from abstract classes or interfaces and only #Override (implement) abstract methods. A better design of your code would be:
abstract class BasePrinter {
public void druckauftrag() {
// ...
drucke();
}
public void drucke();
}
class p extends BasePrinter {
public void drucke() {
System.out.println("B/W-Printer");
}
}
class cp extends BasePrinter {
public void drucke() {
System.out.println("Color-Printer");
}
}
But of course constraints don't always allow for that kind of redesign. Passing the base requirements as parameters to the constructor (dependency injection) instead of extending a base class can also be a good alternative:
interface Druckable {
void drucke();
}
class Druckauftrager {
Druckable dk;
Druckauftrager(Drukable dk){
this.dk = dk;
}
public void druckauftrag() {
// ...
dk.drucke();
}
}
class p implements Druckable {
public void drucke() {
System.out.println("B/W-Printer");
}
}
class cp implements Druckable {
public void drucke() {
System.out.println("Color-Printer");
}
}
Now, if you want to express that a printer requires or can have multiple printing capabilities (like both color and b/w), you just write the class with as much extra Drukable properties and constructor parameters as you want, for example:
class BlackAndWhiteOrColorPrinter {
p blackAndWhitePrintService;
cp colorPrintService;
Druckable selectedPrintService;
BlackAndWhiteOrColorPrinter (p blackAndWhitePrintService, cp colorPrintService){
this.blackAndWhitePrintService = blackAndWhitePrintService;
this.colorPrintService = colorPrintService;
this.selectedPrintService = blackAndWhitePrintService;
}
public void druckauftrag() {
// ...
selectedPrintService.drucke();
}
}
This way, you can even write a class MultiPrinter with a MultiPrinter(List<Druckable> printServices) constructor and add any number of printing modes to its list of printing services: p, cp, and whatever other implementation of Druckable with its public void drucke() comes in the future. It is also extra practical if you want to introduce unit testing, so you can provide mockup objects that force the particular conditions you want to test, like druke() throwing a PaperJamException, for example.
For more information on how interfaces, overriding and inheritance work, see https://docs.oracle.com/javase/tutorial/java/IandI/usinginterface.html
BTW, acording to the latest revision of the official java code conventions guide and also by de facto standard, classes in Java should use CamelCase naming convention. You can also benefit greatly from using semanting naming on all your definitions, like BlackAndWhitePrinter blackAndWhitePrinter and ColorPrinter colorPrinter.
colorprinter is an instance of cp. Even when you upcast it to p, it's drucke() method will be still the one from cp.
The difference is that after you upcast colorprinter, you will not be able to invoke the methods that cp defines on its own.
When you create an object using new operator, memory is allocated in heap. Methods and fields are actually there depending upon the concrete actual class of the object.
Alter a sub class overrides and modifies a behavior from its super class, invoking the overridden method will always result in the modified behavior. Casting will only mean that the object of sub class is now represented by the super type as the object has a modified behavior for a method will always result in the modified behavior.
Suppose you have below classes
public class Fruit{
public void taste(){
System.out.println("depends upon the actual fruit");
}
}
public class Mango extends Fruit{
#Override
public void taste(){
System.out.println("sweet");
}
public void wayToExposeSuperMethod(){
super.taste();
}
}
In other words its like calling mango as a fruit but still mango remains mango.
For above code
Fruit fruit = new Mango();
fruit.taste(); // <-- this will output : sweet
((Mango)fruit).taste();// <-- this will output : sweet
fruit.wayToExposeSuperMethod(); // <-- this will not compile
((Mango)fruit).wayToExposeSuperMethod(); // <-- this will output : depends upon the actual fruit

How to create a method in a Java class that is accesible from only one other class

I was wondering if anyone had a pattern that would help me achieve the following:
We have a JPA entity called Employee and on it there is a setLineManager method. We also have a separate updateLineStructureService, which is a Spring-managed service bean. We want to try and ensure that this setLineManager method can only be called from updateLineStructureService and not directly from any other class.
Is there a way to allow the service access to this method without exposing it to any other classes? I am aware that I could give the method package level access and put the service in the same package as Employee, but that will not fit our package structure so I would prefer not to do that. I am also aware that I could make the method private and just access it through reflection in this one place, but I do not like that solution at all.
Any ideas?
You can inspect the stacktrace (using Throwable#getStackTrace()) and see if it contains the allowed method on specified position.
In the following code snippet, System.PrivateEmployee is not visible outside the System class. Thus effectively privateMethod is private and can only be called from within the System class. Since System.PrivateEmployee extends System.PublicEmployee it can be used outside the System class as System.PublicEmployee
public class System
{
public static interface PublicEmployee { void publicMethod ( ) ; }
private static interface PrivateEmployee extends PublicEmployee { void privateMethod ( ) ; }
}
Use an inner class only available to the other service class:
public class Employee
{
static {
LineStructureService.registerEmployeeHelper(new EmployeeHelper() {
#Override
public void setLineManager(Employee emp, Object foo) {
emp.setLineManager(foo);
}
});
}
public static void init() {}
private void setLineManager(Object foo) { }
}
public class LineStructureService
{
private static volatile EmployeeHelper _helper;
static {
// ensure that Employee class is loaded and helper registered
Employee.init();
}
public static synchronized void registerEmployeeHelper(EmployeeHelper helper) {
_helper = helper;
}
public void doSomething(Employee emp)
{
// now this class can call setLineManager on Employee
_helper.setLineManager(emp, blah);
}
public interface EmployeeHelper {
public void setLineManager(Employee emp, Object foo);
}
}
The only way that a class can access private methods of other classes is with inner classes. If that is not an option, this can't be done.
One approach is to make two forms of Employee.
"BasicEmployee" has all the methods except setLineManager(). "ExtendedEmployee" extends BasicEmployee and adds a public void setLineManager(). (I'm assuming these are classes, but they could also be interfaces instead) Underneath the hood, everything is really a FullEmployee (for clarity, you could make BasicEmployee abstract). But, in the code, in all the classes except UpdateLineStructureService, you declare it as a BasicEmployee. Only in UpdateLineStructureService is it declared as a FullEmployee. So, only UpdateLineStructureService has easy access to setLineManager()
Now, a rogue coder could always cast their BasicEmployee to an ExtendedEmployee to access setLineManager(), so this isn't totally secure. But it's a reasonable pattern to limit access.
You could use AOP (e.g. AspectJ or CDI) to intercept the call to setLineManager(); if the caller is updateLineStructureService() call the method; if not do nothing, or raise an exception or whatever.

Java Inheritance - calling superclass method

Lets suppose I have the following two classes
public class alpha {
public alpha(){
//some logic
}
public void alphaMethod1(){
//some logic
}
}
public class beta extends alpha {
public beta(){
//some logic
}
public void alphaMethod1(){
//some logic
}
}
public class Test extends beta
{
public static void main(String[] args)
{
beta obj = new beta();
obj.alphaMethod1();// Here I want to call the method from class alpha.
}
}
If I initiate a new object of type beta, how can I execute the alphamethod1 logic found in class alpha rather than beta? Can I just use super().alphaMethod1() <- I wonder if this is possible.
Autotype in Eclipse IDE is giving me the option to select alphamethod1 either from class alpha or class beta.
You can do:
super.alphaMethod1();
Note, that super is a reference to the parent class, but super() is its constructor.
Simply use super.alphaMethod1();
See super keyword in java
You can't call alpha's alphaMethod1() by using beta's object But you have two solutions:
solution 1: call alpha's alphaMethod1() from beta's alphaMethod1()
class Beta extends Alpha
{
public void alphaMethod1()
{
super.alphaMethod1();
}
}
or from any other method of Beta like:
class Beta extends Alpha
{
public void foo()
{
super.alphaMethod1();
}
}
class Test extends Beta
{
public static void main(String[] args)
{
Beta beta = new Beta();
beta.foo();
}
}
solution 2: create alpha's object and call alpha's alphaMethod1()
class Test extends Beta
{
public static void main(String[] args)
{
Alpha alpha = new Alpha();
alpha.alphaMethod1();
}
}
It is possible to use super to call the method from mother class, but this would mean you probably have a design problem.
Maybe B.alphaMethod1() shouldn't override A's method and be called B.betaMethod1().
If it depends on the situation, you can put some code logic like :
public void alphaMethod1(){
if (something) {
super.alphaMethod1();
return;
}
// Rest of the code for other situations
}
Like this it will only call A's method when needed and will remain invisible for the class user.
Whenever you create child class object then that object has all the features of parent class.
Here Super() is the facilty for accession parent.
If you write super() at that time parents's default constructor is called.
same if you write super.
this keyword refers the current object same as super key word facilty for accessing parents.
Solution is at the end of this answer, but before you read it you should also read what is before it.
What you are trying to do would break security by allowing skipping possible validation mechanisms added in overridden methods.
For now lets imagine we can invoke version of method from superclass via syntax like
referenceVariable.super.methodName(arguments)
If we have classes like
class ItemBox{ //can sore all kind of Items
public void put(Item item){
//(1) code responsible for organizing items in box
}
//.. rest of code, like container for Items, etc.
}
class RedItemsBox extends ItemBox {//to store only RED items
#Override
public void put(Item item){ //store only RED items
if (item.getColor()==Color.RED){
//(2) code responsible for organizing items in box
}
}
}
As you see RedItemsBox should only store RED items.
Regardless which of the below we use
ItemBox box = new RedItemsBox();
RedItemsBox box = new RedItemsBox();
calling
box.put(new BlueItem());
will invoke put method from RedItemsBox (because of polymorphism). So it will correctly prevent BlueItem object from being placed in RedItemBox.
But what would happen if we could use syntax like box.super.put(new BlueItem())?
Here (assuming it would be legal) we would execute version of put method from ItemBox class.
BUT that version doesn't have step responsible for validating Item color. This means that we could put any Item into a RedItemBox.
Existence of such syntax would mean that validation steps added in subclasses could be ignored at any time, making them pointless.
There IS a case where executing code of "original" method would make sense.
And that palce is inside overriding method.
Notice that comments //(1) .. and //(2).. from put method of ItemBox and RedItemBox are quite similar. Actually they represent same action...
So it makes sense to reuse code from "original" method inside overriding method.
And that is possible via super.methodName(arguments) call (like from inside put of RedItemBox):
#Override
public void put(Item item){ //store only RED items
if (item.getColor()==Color.RED){
super.put(item); // <<<--- invoking code of `put` method
// from ItemBox (supertype)
}
}
beta obj = new beta();
Since you have created beta object , you cant refer directly to alphamethod1 of alpha object.
It can be modified as
class Beta extends Alpha
{
public void alphaMethod1()
{
super.alphaMethod1();
}
}

How do I make sure a super method is called in a child?

If I have the method public void send() { /* some code */ } in a class and have a child of this class also have a method public void send() { /* some code*/ }, how do I ensure that the child must call super.send() somewhere in the send() method that it's trying to override?
I was wondering about this because I've written in APIs where if you don't call the super of that method when overriding it, it'll throw an exception telling me that I haven't called the super method. Is this hard coded or can this be done with some keywords in Java?
You can't really, but you can...
class MySuperClass {
public final void send() {
preSend();
// do the work...
postSend();
}
protected void preSend() {
// to be overridden in by sub classes
}
protected void postSend() {
// to be overridden in by sub classes
}
}
You can do this by adding an abstract method (don't see another way) :
abstract class MyClass
{
public final void send() // forbid changing this.
{
// do something
doSend():
}
protected abstract doSend(); // no external calls
}
http://en.wikipedia.org/wiki/Call_super
What you're trying to do is an anti-pattern; you can do it (many Java core classes do), but you shouldn't - unless you have a really good reason for it.
Except for this bit, all answers provided here are correct.
Conceptually, this is like 'delegating to a child'. To achieve this, the parent class should implement final method which invoke an abstract method, which the child is supposed to implement.
abstract class Parent {
public final void invoke() {
// pre invoke code
doInvoke():
// post invoke code
}
protected abstract doInvoke(); // child should implement this
}
You can't really force a subclass to call the base one. One thing you can do is to change your send method into a base (final) "send" and a "sendcore" (virtual) which would be overriden by the subclasses. The base "send" would set some flag stating that "sendcore" hasn't been called, and then call "sendcore". When it returns it can check whether the child "sendcore" has called the base class.
There is no keyword that enforces this. In my opinion, you either
Provide the subclass with all the information (via protected methods or what not) it needs to completely override and change the send call itself, or...
Document the API so that it is known that they must eventually call send themselves via super. I would imagine most people who are overriding a superclass method would do this if enough of the class is abstracted anyway.
There's nothing built into Java to enforce calling a superclass method. One approach to this is to use private flags in the superclass together with a delegation method. Something like this:
public class Super {
private boolean inSend;
private boolean superCalled;
public final void send() {
inSend = true;
superCalled = false;
doSend();
inSend = false;
if (!superCalled) {
throw new IllegalStateException("Failed to call super.doSend()");
}
}
protected void doSend() {
if (!inSend) {
throw new IllegalStateException("Cannot call doSend() directly");
}
superCalled = true;
// base class functionality
}
}

Categories

Resources