Using different method depending on class in Java - java

I'm trying to reduce some code duplication. Currently i got two methods that are almost identical, the major difference being calling two separate methods within them.
Below is basically what i wanna do:
private void combinedMethod(StandardClass sc, MyClass mc)
{
Method m = null;
if(mc instanceof MySubClass1)
m = sc.RelevantFor1();
if(mc instanceof MySubClass2)
m = sc.RelevantFor2();
m(mc.getA(), mc.getB());
}
I've tested (and it works) this using reflection. But is there a better way of doing it? I read somewhere that reflection is slow and only to be used as a last resort. Is it in this case?
Also in this case the StandardClass is a standard class in the java api. The Class I send in is of my own making.

It isn't clear how exactly those methods look like, or what they are doing, but it seems like a perfect polymorphism case. You can create a method in super class - MyClass I suppose in this case. And override those methods in your subclasses.
Now, when you call that method on MyClass reference, appropriate subclass method will be called based on actual instance. Now invoke whatever method you want to invoke in respective overridden methods.
Somewhere along the lines of:
class MyClass {
public void method(StandardClass sc) { }
}
class MySubClass1 extends MyClass {
public void method(StandardClass sc) {
sc.method(getA(), getB());
}
}
class MySubClass2 extends MyClass {
public void method(StandardClass sc) {
sc.anotherMethod(getA(), getB());
}
}
And then your combinedMethod looks like:
private void combinedMethod(StandardClass sc, MyClass c) {
c.method(sc);
}

Related

Is there any best practice on java Super.call?

public boolean sendRequest(final Object... params) {
if (!super.sendRequest(params)) {
return false;
}
...
// Some Log code or tracing code here
...
}
Why not implement a new method to call sendRequest rather than overwrite?
public boolean Send(final Object... params){
if (!super.sendRequest(params)) {
return false;
}
...
// Some Log code or tracing code here
...
}
Do you want your class with the override to be able to be used in the same way as members of the original class? i.e.:
...
class MyClass extends TheirClass {
#Override
void doIt() {
super.doIt();
// also do my stuff
}
}
...
// the doSomething function is part of the library where TheirClass lives.
// I can pass instances of MyClass to it, and doIt will be called, because MyClass IS-A TheirClass
theirFunction.doSomething(new MyClass(...));
...
But perhaps you just want to use the functionality of doIt, but don't need to use and code which expects a TheirClass.
In that case it is probably better to use composition rather than inheritance:
class MyClass {
private final TheirClass theirClass;
public MyClass(TheirClass theirClass) {
this.theirClass = theirClass;
}
public void doMyStuff() {
theirClass.doIt();
// and do some other things
}
}
This is better than inheritance with a new method name, because then you would have two methods on the class which do about the same thing (except the original doIt doesn't do your stuff), and it may not be clear which should be called.
Even inheritance where you override the method may have problems. We don't know what code in TheirClass calls doIt, so perhaps the code we've added will be called when we don't expect it to be.
Overall, composition should be preferred to inheritance whenever possible.

Check is instance method is called from a constructor

I would like to check, from an instance method of a non-final class, whether the constructors and initializers of that class and its chain of subclasses for the specific instance have already completed.
In the following example, I have a class Abstract, which can be used to implement an interface which allows listeners to be added (which, for simplicity, are just Runnable instances here) and which provides a method signalEvent() which calls all attached listeners.
abstract class Abstract {
protected final void signalEvent() {
// Check that constructs have run and call listeners.
}
public final void addListener(Runnable runnable) {
...
}
}
class Concrete extends Abstract {
Concrete() {
// Should not call signalEvent() here.
}
void somethingHappened() {
// May call signalEvent() here.
}
}
Now it is possible to call signalEvent() from within the subclass constructor, but there is no way that a listener has already been added by that time and the event would just be lost. In our code-base, once in a while, someone adds such a call and I would like to be able to catch such calls as early as possible (using an assert statement or similar).
Is it possible to check whether an instance method is being called, directly or indirectly, from the subclass constructor or initializer of the current instance or, alternatively, is it possible to check whether all constructors for an instance have been completed?
In short, there is no elegant Java mechanism that allows you to do that, but you may consider using a factory pattern. Instead of creating instances directly using new keyword, you could create a factory class, that takes care of creating the actual instance and invokes an additional "post-create" method, that lets the instance know it's been completely created.
If you're using some dependency injection like spring, you get that out of the box, but if not, a solution could look something like this:
interface PostConstruct { // the classes need to implement that
void postConstruct();
}
public class InstanceFactory {
public <T extends PostConstruct> T create(Class<T> clazz, Object... params) {
T instance = //create using reflection
instance.postConstruct();
return instance;
}
}
A solution to the problem to see if a method or code is being called from a constructor. The code below will print true and false respectivly but would be slow and not pretty at all.
I still believe it is not the right solution for the problem above. As Codbender said, better to check if a listener has been added or set a status variable which would be faster
Edit - fixed the issue that Codebender mentioned and also made sure to check back in the stack trace incase of being called a couple of methods deep
public class TestClass extends TestAbstract {
public TestClass() throws Exception {
submethod();
}
public void submethod() throws Exception {
System.out.println(isInConstructor());
}
public static void main(String[] args) throws Exception {
System.out.println(new TestClass().isInConstructor());
}
}
public class TestAbstract {
public boolean isInConstructor() throws Exception {
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
for (StackTraceElement element : elements) {
if (element.getMethodName().equals("<init>") &&
TestAbstract.class.isAssignableFrom(Class.forName(element.getClassName()))) {
return true;
}
}
return false;
}
}

How to pass a concrete method as parameter to another concrete method

I am newbie to java, and developing a real life project. I have many methods and about 2500 lines of code thus far. Many of the methods are slightly different(usually a difference of mere a single identifier) due to which i have to copy the code again and again with slight changes.
What i want is to pass a method as parameter to another method, I've gone through lambda expressions
but i could not find it enough appealing, off-course due to my own conceptual shortcomings. because it tells to define functional interface of each method to be passed. but as per my thoughts it would not give me a generic code so that i would be able to simply add some other Tables in future.
i am putting a piece of code to demonstrate and better explain my problem.
if(houseTabPanel.getComponentCount()==0){
houseTableDb();
}
if(isSelected){
selection(houseTable);
}
else {
houseTable.setColumnSelectionAllowed(false);
houseTable.setRowSelectionAllowed(false);
houseTable.setCellSelectionEnabled(false);
Rselection(houseTable);
}
now i have different methods named houseTableDb() , plotTableDb() , adminTableDb() etc.
i want to make a method of this piece of code and pass plotTableDb() etc as parameter..
something like...
public void genericMethod(JPanel p, JTable t, some method reference to use instead of houseTableDb){}
pardon me if am not descriptive enough.. any response would be truly appreciated by core of the heart.
Provided that all of these methods have the same signature you can define an interface with a single method with that signature (return value, parameter list). Then you write classes implementing the method, one for each method's implementation. For passing the method, you create an object of that class and pass the object. The call to the actual method is replaced by the call to the method defined in the interface.
interface Callee {
void meth();
}
class MethOne implements Callee {
public void meth(){...}
}
void caller( Callee callee ){
callee.meth();
}
Callee ofOne = new MethOne();
caller( ofOne );
But to avoid all this hazzle: that's why lambdas have been added...
You can do like this :
public void genericMethod(JPanel p, JTable t, TableDbCallBack tableDb)
{
if(p.getComponentCount()==0)
{
tableDb.run();
}
if(isSelected)
{
selection(t);
}
else
{
t.setColumnSelectionAllowed(false);
t.setRowSelectionAllowed(false);
t.setCellSelectionEnabled(false);
Rselection(t);
}
}
usage :
genericMethod(p, t, new HouseTableDb());
genericMethod(p, t, new AdminTableDb());
Implementation :
public interface TableDbCallBack extends Runnable {}
public class HouseTableDb implements TableDbCallBack
{
#Override
public void run()
{
// Whatever it should do
}
}
public class AdminTableDb implements TableDbCallBack
{
#Override
public void run()
{
// Whatever it should do
}
}

Using methods from a subclass on an object that is an instance of the superclass

Let's say there's a class that I use extensively and is returned by a method.
CommonClass obj = getCommonObject();
Now I want to extend this class to create some utility method to avoid repeating myself.
public CommonClassPlus extends CommonClass {
public String dontRepeatYourself() {
// the reason I'm creating a subclass
}
}
Of course I would like to use my improved class for the method above, however, downcasting isn't allowed.
CommonClassPlus obj = getCommonObject();
//Cannot cast to CommonClassPlus
How can I use the method dontRepeatYourself() if I can only work with the object that is an instance of the superclass?
CommonClass and getCommonObject() are from an external library and I cannot change them.
You cannot add behavior to an existing instance in Java (like you could in JavaScript, for example).
The closest you can get in Java is the Decorator pattern:
CommonClassPlus obj = decorate(getCommonObject());
where decorate() is
public CommonClassPlus decorate(CommonClass x) {
return new CommonClassPlus(x);
}
This approach creates a potentially huge amount of boilerplate because it must delegate each method call to the wrapped instance. If a method in CommonClass is final and there is no interface you can reimplement, then this approach fails altogether.
In most cases you will be able to get along with a simple static helper method:
public static String dontRepeatYourself(CommonClass x) {
...
}
If CommonClass is from an external library, you probably want to wrap it in an Adapter Pattern anyway, using the principle of Composition over Inheritance.
This gives you complete control if you want to, say, change the library you're using, and allows you to add functionality like dontRepeatYourself().
public class CommonClassAdapter implements MyAdapter {
private final CommonClass common;
private final String cachedResult;
// Note that I'm doing dependency injection here
public CommonClassAdapter(CommonClass common) {
this.common = common;
// Don't expose these because they shouldn't be called more than once
common.methodIOnlyCallOnce();
cachedResult = common.anotherMethodIOnlyCallOnce();
}
#Override
public void someMethod() {
common.someMethodWithDifferentName();
}
#Override
public String dontRepeatYourself() {
return cachedResult;
}
}
Note also that most modern IDEs have things like Eclipse's Source -> Generate Delegate Methods to make this process faster.

Java Method Overriding - accessing methods in parent - is this possible?

Let's say I create an instance of a class and override one of its methods at the same time - like this
MyClass fred = new MyClass() {
#Override
public void mymethod() {
super.mymethod();
//call something here
}
};
Now let's imagine I want to call a local method which has the SAME name and SAME (lack of) parameters as my overridden method - e.g. I have
public void mymethod() {
//my stuff in here
}
How can I call that from within the overridden method (on the line //call something here)???
Is that even possible? Using
this.mymethod();
causes an endless loop (the overriden method is simply calling itself)
Is there a way of accessing this method (other than via a static reference perhaps?)
Sorry if this is a common question - it's a hard thing to search for and the one question I found had no replies and wasn't really that well-phrased so I'm trying myself!!
I don't have a complier handy so I'm not 100% sure here, but try this:
ParentClass.this.myMethod();
An ugly, but functioning solution:
final MyOtherClass parent = this;
MyClass fred = new MyClass() {
#Override
public void mymethod() {
super.mymethod();
parent.mymethod();
}
};
I'm struggling to see the scenario where you need to do this for naming purposes, but it's useful to know that this in the anonymous class will refer to the anonymous class, not the "parent"; so if you find the need to access the parent's method it's a useful technique.
FWIW, here's a working example.
I am not sure if I fully understood the question but my guess is that you want something like this:
public class ParentClass {
public void mymethod() {
....
}
public void someOtherMethod() {
MyClass fred = new MyClass() {
#Override
public void mymethod() {
super.mymethod();
//call something here
ParentClass.this.mymethod();
}
}
}
}
Note ParentClass.this.mymethod()

Categories