class Base {
Base() {
System.out.println("Base Constructor");
}
}
class Derived1 extends Base {
private static String pattern = "a+b+";
Derived1() {
super();
System.out.println("Derived 1 Constructor");
}
public static boolean doesMatch(String v) {
return v.matches(pattern);
}
}
class Derived2 extends Base {
private static String pattern = "c+";
Derived2() {
super();
System.out.println("Derived 2 Constructor");
}
public static boolean doesMatch(String v) {
return v.matches(pattern);
}
}
class Builder {
public static Base baseFromString(String v) throws Exception {
if (Derived1.doesMatch(v)) return new Derived1();
if (Derived2.doesMatch(v)) return new Derived2();
throw new Exception("Could not match " + v + " to any derived type.");
}
}
class Test {
public static void main(String[] args) throws Exception {
Base b = Builder.baseFromString("aaab");
}
}
The code above has a primary problem I want to solve:
The doesMatch method is repeated code for the two derived classes. I'd like to move it to the base class, but then it won't be able to access the pattern member. How do I structure my code better so that each derived class can have its own static pattern, while they all share the same base doesMatch method?
I've tried messing around with abstract classes and interfaces, but I couldn't get anything to work. I am fine with those types of solutions as long as there is a hierarchy where the derived classes either extend or implement the base class.
Secondary question (from original post)
I might want to add several more derived classes. I'd like to not have to update the baseFromString method with another if every time I extend the base class. Is this something that can be solved with polymorphism?
A functional technique (Java 9+), but there is some performance overhead:
class Base {
Base() {
System.out.println("Base Constructor");
}
}
class Derived1 extends Base {
Derived1() {
super();
System.out.println("Derived 1 Constructor");
}
}
class Derived2 extends Base {
Derived2() {
super();
System.out.println("Derived 2 Constructor");
}
}
interface NewBase {
Base create();
}
final class Pattern {
final private String pattern;
final private NewBase newBase;
public Pattern(String pattern, NewBase newBase) {
this.pattern = pattern;
this.newBase = newBase;
}
public String getPattern() {
return pattern;
}
public NewBase getNewBase() {
return newBase;
}
}
class Builder {
final private static List<Pattern> newObjects = new ArrayList<>();
private static void addPattern(String pattern, NewBase newObject) {
newObjects.add(new Pattern(pattern, newObject));
}
static {
addPattern("a+b+", Derived1::new);
addPattern("c+", Derived2::new);
}
public static Base baseFromString(String v) throws Exception {
for (Pattern p : newObjects) {
if (v.matches(p.getPattern()))
return p.getNewBase().create();
}
throw new Exception("Could not match " + v + " to any derived type.");
}
}
Just update the static Builder initializer to call the addPattern for new patterns and derived classes.
You can't do that, at least not with static members. The problem is that static members cannot be overridden.
public class Driver {
public static void main(String args[]) {
Derived aDerived = new Derived();
aDerived.print(); // prints "Value is 5", not "Value is 10"
}
}
public class Base {
protected static final int VALUE = 5;
public Base() {}
protected void print() {
System.out.println("Value is " + VALUE);
}
}
public class Derived extends Base {
protected static final int VALUE = 10; // does not override base Value
public Derived() {}
}
Each subclass can have its own value, and they would all inherit print(). But it doesn't do what you want because print() will always reference Base.VALUE even in the inherited Derived.print().
So, static doesn't work. I assume that you feel the pattern member needs to be static because there only needs to be one copy of the pattern value for the entire class. That one copy part should have tipped you off to a handy little design pattern: the singleton pattern!
public class Driver {
public static void main(String args[]) {
Derived aDerived = new Derived();
aDerived.print(); // prints "Value is 10"
}
}
public class Base {
protected Value val = Value.getInstance();
public Base() {}
protected void print() {
System.out.println("Value is " + val.value());
}
}
public class Derived extends Base {
public Derived() { val = DerivedValue.getInstance(); }
}
public class Value {
private int value = 5;
public int value() { return value; }
private static Value instance = new Value();
protected Value() {}
public static Value getInstance() { return instance; }
}
public class DerivedValue extends Value {
private int value = 10;
public int value() { return value; }
private static DerivedValue instance = new DerivedValue();
private DerivedValue() {}
public static DerivedValue getInstance() { return instance; }
}
There's a lot more code in this version, but now there is only one copy of the two different values used.
Note: Below is how you can make the value members final. You'll have to set up your packages appropriately so the protected Base(Value v) constructor is only visible to the Derived class.
public class Base {
protected final Value val;
public Base() { val = Value.getInstance(); }
protected Base(Value v) { val = v; }
protected void print() {
System.out.println("Value is " + val.value());
}
}
public class Derived extends Base {
public Derived() { super(DerivedValue.getInstance()); }
}
I want to write a method which would receive different type of objects dynamically. Once I receive the dynamic object, I have logic inside method to do something based on the properties associated with that object. It would be something like below:
MainClass{
class1 obj1;//all these are pojo
class2 obj2;
class3 obj3;
method1(<dynamic_object>)
}
method1(<dynamic_object>){
if(dynamic_object.property 1 == true){
callmethod2(dynamic_object.property 1)
}
else{
callmethod3(dynamic_object.property 1)
}
}
Here dynamic_objects are of different type.
How can I achieve this in Java? I do not want to use reflection here.
In order to recognize the type of the object you can use the instanceof operator.
private void instanceOfMethodExample(Object object){
if(object instanceof String)
print("Its a String!");
else if(object instanceof Integer)
print("Its an Int!");
else
print("Its a " + object.getClass().getName()); // by calling getClass().getName() method you take the class name of the object as a String
}
Use the visitor pattern, In a nutshell you can have something like this:
public class Visitor {
interface UserVisitor {
public void visit(CarUser user1);
public void visit(BusUser user2);
}
static class VehicleVisitor implements UserVisitor {
private Car vehicle;
private Bus bus;
VehicleVisitor(Car vehicle, Bus bus) {
this.vehicle = vehicle;
this.bus = bus;
}
public void visit(CarUser user1) {
user1.setCar(vehicle);
}
public void visit(BusUser user2) {
user2.setBus(bus);
}
}
interface UserVisitorClient {
void accept(UserVisitor visitor);
}
static class CarUser implements UserVisitorClient {
private Car car;
public void accept(UserVisitor visitor) {
visitor.visit(this);
}
public void setCar(Car car) {
this.car = car;
}
public Car getCar() {
return car;
}
}
static class BusUser implements UserVisitorClient {
private Bus bus;
public void accept(UserVisitor visitor) {
visitor.visit(this);
}
public void setBus(Bus bus) {
this.bus = bus;
}
public Bus getBus() {
return bus;
}
}
static class Car {
#Override
public String toString() {
return "CAR";
}
}
static class Bus {
#Override
public String toString() {
return "BUS";
}
}
public static void main(String[] args) {
List<UserVisitorClient> users = new ArrayList<UserVisitorClient>();
CarUser user1 = new CarUser();
users.add(user1);
BusUser user2 = new BusUser();
users.add(user2);
for (UserVisitorClient user : users) {
VehicleVisitor visitor = new VehicleVisitor(new Car(), new Bus());
user.accept(visitor);
}
System.out.println(user1.getCar());
System.out.println(user2.getBus());
}
}
Which is just an example. But it shows that basically you can use this pattern to support what you're trying to accomplish.
In your code, you could have:
void method1(VisitorClient client) {
client.accept(someVisitor);
}
This will allow you to reach o more object oriented solution, relying in polymorphism instead of reflection or instanceof.
The best option is to use a common interface
interface HasProperty {
boolean isSet();
}
void method1(HasProperty object) {
if (object.isSet())
method2(object);
else
method3(object);
}
Or even better have a method to call to perform an action.
interface MethodOne {
void method1();
}
MethodOne object = ...
object.method1(); // calls the appropriate method for this object.
Use superclass of all objects- "Object" and check the type of object using instanceof operator.
method1(Object obj){
if(obj instanceof dynamic_object){
callmethod2(dynamic_object.property 1)
}
else if(obj instanceof dynamic_object2) {
callmethod3(dynamic_object2.property 1)
}
}
EDIT: Given your newly posted code, you may even simply wish to use an common interface, or base class, for the dynamic objects.
Interface:
public interface CommonInterface {
boolean isValid();
void method1();
void method2();
void method3();
}
Class Example:
public Class1 implements CommonInterface {
public boolean isValid() {
return true;
}
public void method1() {
System.out.println("Method 1");
}
public void method2() {
System.out.println("Method 2");
}
public void method3() {
System.out.println("Method 2");
}
}
Code:
public void doSomethingWithCommonObjects(CommonInterface object) {
object.method1();
if (object.isValid()) {
object.method2();
} else {
object.method3();
}
}
Each of the dynamic objects simply need to implement the CommonInterface interface, which would enforce method1(), method2(), method3() and property1() signatures for each object to implement.
Previous answer details for reference:
You will either have to use Java Generics, potentially with some common interface or base class for the objects in question so that you can then call their methods.
E.g.
public static <T extends Comparable<T>> T maximum(T x, T y, T z) {
T max = x; // assume x is initially the largest
if (y.compareTo(max) > 0) {
max = y; // y is the largest so far
}
if (z.compareTo(max) > 0) {
max = z; // z is the largest now
}
return max; // returns the largest object
}
If, however, you require to call particular methods without knowing the interface for those methods beforehand programmatically, then you're into Reflection territory.
Say I have a class with many of public methods:
public class MyClass {
public void method1() {}
public void method2() {}
(...)
public void methodN() {}
}
Now I would like to create a wrapper class which would delegate all the methods to wrapped instance (delegate):
public class WrapperClass extends MyClass {
private final MyClass delegate;
public WrapperClass(MyClass delegate) {
this.delagate = delegate;
}
public void method1() { delegate.method1(); }
public void method2() { delegate.method2(); }
(...)
public void methodN() { delegate.methodN(); }
}
Now if MyClass has a lot of methods I would need to override each of them which is more or less the same code which just "delegates". I was wondering if it is possible to do some magic to automatically call a method in Java (so the Wrapper class would need to say "Hey if you call a method on me just go to delegate object and call this method on it).
BTW: I can not use inheritance because the delegate is not under my control.I just get its instance from elsewhere (another case would be if MyClass was final).
NOTE: I do not want IDE generation. I know I can do it with help of IntelliJ/Eclipse, but I'm curious if this can be done in code.
Any suggestions how to achieve something like this? (NOTE: I would probably be able to do it in some scripting languages like php where I could use php magic functions to intercept the call).
Perhaps the dynamic Proxy of java can help you. It only works if you consequently use interfaces. In this case, I will call the interface MyInterface and set up a default implementation:
public class MyClass implements MyInterface {
#Override
public void method1() {
System.out.println("foo1");
}
#Override
public void method2() {
System.out.println("foo2");
}
#Override
public void methodN() {
System.out.println("fooN");
}
public static void main(String[] args) {
MyClass wrapped = new MyClass();
wrapped.method1();
wrapped.method2();
MyInterface wrapper = WrapperClass.wrap(wrapped);
wrapper.method1();
wrapper.method2();
}
}
The wrapper class implementation would look like:
public class WrapperClass extends MyClass implements MyInterface, InvocationHandler {
private final MyClass delegate;
public WrapperClass(MyClass delegate) {
this.delegate = delegate;
}
public static MyInterface wrap(MyClass wrapped) {
return (MyInterface) Proxy.newProxyInstance(MyClass.class.getClassLoader(), new Class[] { MyInterface.class }, new WrapperClass(wrapped));
}
//you may skip this definition, it is only for demonstration
public void method1() {
System.out.println("bar");
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method m = findMethod(this.getClass(), method);
if (m != null) {
return m.invoke(this, args);
}
m = findMethod(delegate.getClass(), method);
if (m != null) {
return m.invoke(delegate, args);
}
return null;
}
private Method findMethod(Class<?> clazz, Method method) throws Throwable {
try {
return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
return null;
}
}
}
Note that this class:
extends MyClass, to inherit a default implementation (any other would do)
implements Invocationhandler, to allow the proxy to do reflection
optionally implement MyInterface (to satisfy the decorator pattern)
This solution allows you to override special methods, but to delegate all others. This will even work with sub classes of Wrapper class.
Note that the method findMethod does not yet capture the special cases.
This question is 6 months old already and #CoronA's wonderful answer has satisfied and been accepted by #walkeros, but I thought I would add something here as I think this can be pushed an extra step.
As discussed with #CoronA in the comments to his answer, instead of having to create and maintain a long list of MyClass methods in WrapperClass (i.e. public void methodN() { delegate.methodN(); }), the dynamic proxy solution moves this to the interface. The issue is that you still have to create and maintain a long list of signatures for the MyClass methods in the interface, which is perhaps a bit simpler but doesn't completely solve the problem. This is especially the case if you don't have access to MyClass in order to know all the methods.
According to Three approaches for decorating your code,
For longer classes, a programmer must choose the lesser of two evils:
implement many wrapper methods and keep the type of decorated object
or maintain a simple decorator implementation and sacrifice retaining
the decorated object type.
So perhaps this is an expected limitation of the Decorator Pattern.
#Mark-Bramnik, however, gives an fascinating solution using CGLIB at Interposing on Java Class Methods (without interfaces). I was able to combine this with #CoronaA's solution in order to create a wrapper that can override individual methods but then pass everything else to the wrapped object without requiring an interface.
Here is MyClass.
public class MyClass {
public void method1() { System.out.println("This is method 1 - " + this); }
public void method2() { System.out.println("This is method 2 - " + this); }
public void method3() { System.out.println("This is method 3 - " + this); }
public void methodN() { System.out.println("This is method N - " + this); }
}
Here is WrapperClass which only overrides method2(). As you'll see below, the non-overridden methods are, in fact, not passed to the delegate, which can be a problem.
public class WrapperClass extends MyClass {
private MyClass delagate;
public WrapperClass(MyClass delegate) { this.delagate = delegate; }
#Override
public void method2() {
System.out.println("This is overridden method 2 - " + delagate);
}
}
Here is MyInterceptor which extends MyClass. It employs the proxy solution using CGLIB as described by #Mark-Bramnik. It also employs #CononA's method of determining whether or not to send the method to the wrapper (if it is overridden) or the wrapped object (if it is not).
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class MyInterceptor extends MyClass implements MethodInterceptor {
private Object realObj;
public MyInterceptor(Object obj) { this.realObj = obj; }
#Override
public void method2() {
System.out.println("This is overridden method 2 - " + realObj);
}
#Override
public Object intercept(Object arg0, Method method, Object[] objects,
MethodProxy methodProxy) throws Throwable {
Method m = findMethod(this.getClass(), method);
if (m != null) { return m.invoke(this, objects); }
Object res = method.invoke(realObj, objects);
return res;
}
private Method findMethod(Class<?> clazz, Method method) throws Throwable {
try {
return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
return null;
}
}
}
Here is Main and the results you get if you run it.
import net.sf.cglib.proxy.Enhancer;
public class Main {
private static MyClass unwrapped;
private static WrapperClass wrapped;
private static MyClass proxified;
public static void main(String[] args) {
unwrapped = new MyClass();
System.out.println(">>> Methods from the unwrapped object:");
unwrapped.method1();
unwrapped.method2();
unwrapped.method3();
wrapped = new WrapperClass(unwrapped);
System.out.println(">>> Methods from the wrapped object:");
wrapped.method1();
wrapped.method2();
wrapped.method3();
proxified = createProxy(unwrapped);
System.out.println(">>> Methods from the proxy object:");
proxified.method1();
proxified.method2();
proxified.method3();
}
#SuppressWarnings("unchecked")
public static <T> T createProxy(T obj) {
Enhancer e = new Enhancer();
e.setSuperclass(obj.getClass());
e.setCallback(new MyInterceptor(obj));
T proxifiedObj = (T) e.create();
return proxifiedObj;
}
}
>>> Methods from the unwrapped object:
This is method 1 - MyClass#e26db62
This is method 2 - MyClass#e26db62
This is method 3 - MyClass#e26db62
>>> Methods from the wrapped object:
This is method 1 - WrapperClass#7b7035c6
This is overridden method 2 - MyClass#e26db62
This is method 3 - WrapperClass#7b7035c6
>>> Methods from the proxy object:
This is method 1 - MyClass#e26db62
This is overridden method 2 - MyClass#e26db62
This is method 3 - MyClass#e26db62
As you can see, when you run the methods on wrapped you get the wrapper for the methods that are not overridden (i.e. method1() and method3()). When you run the methods on proxified, however, all of the methods are run on the wrapped object without the pain of having to delegate them all in WrapperClass or put all of the method signatures in an interface. Thanks to #CoronA and #Mark-Bramnik for what seems like a pretty cool solution to this problem.
Check the #Delegate annotation from Lombok framework:
https://projectlombok.org/features/Delegate.html
Switch to Groovy :-)
#CompileStatic
public class WrapperClass extends MyClass {
#Delegate private final MyClass delegate;
public WrapperClass(MyClass delegate) {
this.delagate = delegate;
}
//Done. That's it.
}
http://mrhaki.blogspot.com/2009/08/groovy-goodness-delegate-to-simplify.html
You don't have to do this -- your Wrapper class is a subclass of the original class, so it inherits all of its publicly accessible methods -- and if you don't implement them, the original method will be called.
You shouldn't have extends Myclass together with a private MyClass object -- that's really really redundant, and I can't think of a design pattern where doing that is right. Your WrapperClass is a MyClass, and hence you can just use its own fields and methods instead of calling delegate.
EDIT: In the case of MyClass being final, you'd be circumventing the willfull declaration to not allow subclassing by "faking" inheritance; I can't think of anyone willing to do that other than you, who is in control of WrapperClass; but, since you're in control of WrapperClass, not wrapping everything you don't need is really more than an option -- it's the right thing to do, because your object is not a MyClass, and should only behave like one in the cases you mentally considered.
EDIT you've just changed your question to mean something completely different by removing the MyClass superclass to your WrapperClass; that's a bit bad, because it invalidates all answers given so far. You should have opened another question.
Credits go to CoronA for Pointing out the Proxy and InvocationHandler classes. I worked out a more reusable utility class based on his solution, using generics:
public class DelegationUtils {
public static <I> I wrap(Class<I> iface, I wrapped) {
return wrapInternally(iface, wrapped, new SimpleDecorator(wrapped));
}
private static <I> I wrapInternally (Class<I> iface, I wrapped, InvocationHandler handler) {
return (I) Proxy.newProxyInstance(wrapped.getClass().getClassLoader(), new Class[] { iface }, handler);
}
private static class SimpleDecorator<T> implements InvocationHandler {
private final T delegate;
private SimpleDecorator(T delegate) {
this.delegate = delegate;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method m = findMethod(delegate.getClass(), method);
if (m == null) {
throw new NullPointerException("Found no method " + method + " in delegate: " + delegate);
}
return m.invoke(delegate, args);
}
}
private static Method findMethod(Class<?> clazz, Method method) throws Throwable {
try {
return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
return null;
}
}
}
Test it:
public class Test {
public interface Test {
public void sayHello ();
}
public static class TestImpl implements Test {
#Override
public void sayHello() {
System.out.println("HELLO!");
}
}
public static void main(String[] args) {
Test proxy = DelegationUtils.wrap(Test.class, new TestImpl());
proxy.sayHello();
}
}
I wanted to create an automatic delegation class that executes the delegatee's methods on the EDT. With this class, you just create a new utility method that will use an EDTDecorator, in which the implementation will wrap m.invoke in a SwingUtilities.invokeLater.
However, if I reflect on this, I may want to reconsider making a non-Reflection based proxy per interface that I have - it might be cleaner and faster, and more understandable. But, it's possible.
Define a method in WrapperClass i.e. delegate() that returns the instance of MyClass
OR
You can use reflection to do that but the caller has to pass the method name as an argument to an exposed method. And there will be complications regarding the method arguments/overloaded methods etc.
BTW: I can not use inheritance because the delegate is not under my control.I just get its instance from elsewhere (another case would be if MyClass was final)
The code that you have posted has public class WrapperClass extends MyClass
Actually your current implementation of WrapperClass is actually a decorator on top of MyClass
Let me redefine the problem for a specific case.
I want to override the close method of ResultSet interface in jdbc. My aim is to close the preparedstatement in close method of result set. I could not access to the Class (DelegatingResultSet) that implements in ResultSet interface. There are a lot of methods in ResultSet interface and overriding them one by one and calling the corresponding method from the ResultSet object is one solution. For a dynamic solution I used Dynamic ProxyClasses (https://docs.oracle.com/javase/1.5.0/docs/guide/reflection/proxy.html).
// New ResultSet implementation
public class MyResultSet implements InvocationHandler {
ResultSet rs;
PreparedStatement ps;
private Method closeMethod;
public MyResultSet(ResultSet rs, PreparedStatement ps) {
super();
this.rs = rs;
this.ps = ps;
try {
closeMethod = ResultSet.class.getMethod("close",null);
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
public void close() {
try {
rs.close();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static Object newInstance(ResultSet rs, PreparedStatement ps) {
return java.lang.reflect.Proxy.newProxyInstance(rs.getClass().getClassLoader(), rs.getClass().getInterfaces(),
new MyResultSet(rs,ps));
}
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
Object result = null;
try {
Class declaringClass = m.getDeclaringClass();
if (m.getName().compareTo("close")==0) {
close();
} else {
result = m.invoke(rs, args);
}
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
} finally {
}
return result;
}
}
// How to call it:
ResultSet prs = (ResultSet) MyResultSet.newInstance(rs,ps);
I really appreciated #CoronA's answer. I also looked at #Mark Cramer's answer, but, if I'm not missing something, I think that there are always at least two instances of the "proxified" class with a strange relationship beteen the two objects.
This, along with the fact that cglib is now deprecated, pushed me to find a new implementation based on ByteBuddy.
This is what I came up with:
public class MyClass {
public String testMethod() {
return "11111";
}
public String testMethod2() {
return "aaaaa";
}
}
public class MyClassWithDelegate extends MyClass {
private static final Constructor<? extends MyClassWithDelegate> CONSTRUCTOR_WITH_DELEGATE;
static {
Constructor<? extends MyClassWithDelegate> temp = null;
try {
final var instrumentedMyClassWithDelegateType =
new ByteBuddy()
.subclass(MyClassWithDelegate.class)
.method(ElementMatchers.any())
.intercept(MethodDelegation.to(MethodInterceptor.class))
.make()
.load(MyClassWithDelegate.class.getClassLoader())
.getLoaded();
temp = instrumentedMyClassWithDelegateType.getConstructor(MyClass.class);
} catch (final Exception e) {
LOGGER.error("Cannot instrument class {}", MyClassWithDelegate.class, e);
}
CONSTRUCTOR_WITH_DELEGATE = temp;
}
public static MyClassWithDelegate getInstanceWithDelegate(final MyClass myClass) {
try {
return CONSTRUCTOR_WITH_DELEGATE.newInstance(myClass);
} catch (final Exception e) {
LOGGER.error("Cannot get instance of {}", MyClassWithDelegate.class, e);
throw new IllegalStateException();
}
}
private final boolean initialized;
private final MyClass delegate;
public MyClassWithDelegate(final MyClass delegate) {
super();
this.delegate = delegate;
this.initialized = true;
}
public String testMethod() {
return "22222";
}
public static class MethodInterceptor {
#RuntimeType
public static Object intercept(#This final MyClassWithDelegate self,
#Origin final Method method,
#AllArguments final Object[] args,
#SuperMethod final Method superMethod) throws Throwable {
if (!self.initialized || method.getDeclaringClass().equals(MyClassWithDelegate.class)) {
return superMethod.invoke(self, args);
} else {
return method.invoke(self.delegate, args);
}
}
}
}
The initialized field is used to prevent method calls the super constructor from being redirected to the delegate before its assignment (in this case it wouldn't be a problem, but I wanted to create a generic solution).
Every method called on an instance of MyClassWithDelegate will be redirected to the delegate, except from methods declared inside MyClassWithDelegate itself.
In this example, calling testMethod() on an instance of MyClassWithDelegate will return "22222", while testMethod2() will return "aaaaa".
Obviously, the delegation will actually work only if every instance of MyClassWithDelegate is obtained calling the getInstanceWithDelegate factory method.
I have a class in which i have intialized hashmap in static block. Passing the key, I have retrived the value which is a class. In order to create object for this class. I have used the constructor class to get the constructor and passed arguments and created object.
I have two class in hashmap. To create objectfor EchoExpression I need to pass two arguments and for OutExpression class i need to pass only one argument(String).
Question:
Based on the class returned by the key I need to execute which constructor to get and implement, whether the constructor with one argument or two argument.
public class ExampleFactory {
private static HashMap<String,Class<?>> hmap = new HashMap<String,Class<?>>();
static
{
hmap.put("echo", EchoExpression.class);
hmap.put("Out", OutExpression.class);
}
public void getExpo(String key,String expression)
{
Class aClass =map.get(key);
//Constructor implementation for OutExpression where only one argument string is passed
Constructor constructor = aClass.getConstructor(new Class[]{String.class});
Object object= constructor.newInstance(expression);
//constructor for passing two arguments string for EchoExpression
Constructor constructor = aClass.getConstructor(new Class[]{String.class,Class.class});
Object object= constructor.newInstance(expression, Boolean.class);
return null;
}
}
How to choose from the value(class) which class to implement without using if else?
Use an Enum and switch on it. Here is a executable stub without getting too deeply into the reflection or the syntax of your example:
package com.trip.test;
import java.util.HashMap;
import java.util.Map;
public class ExampleFactory {
private static Map<String, Class<?>> hmap = new HashMap<String, Class<?>>();
static {
hmap.put("echo", EchoExpression.class);
hmap.put("Out", OutExpression.class);
}
public static void getExpo(String key, String expression) {
Class aClass = hmap.get(key);
ClassMappingEnum myType = ClassMappingEnum.getClassMappingEnum(aClass);
switch (myType) {
case ECHO_EXPRESSION:{
System.out.println(aClass.getName());
// do something
break;
}
case OUT_EXPRESSION:{
System.out.println(aClass.getName());
// do something
break;
}
case UNKNOWN:
default:
System.out.println("Bummer: " + aClass.getName());
}
}
public static void main(String[] args) {
getExpo("echo", "B");
getExpo("Out", "B");
}
}
enum ClassMappingEnum {
ECHO_EXPRESSION(EchoExpression.class), OUT_EXPRESSION(OutExpression.class), UNKNOWN(null);
private Class typeDes;
private ClassMappingEnum(Class typeDes) {
this.typeDes = typeDes;
}
public static ClassMappingEnum getClassMappingEnum(Class compare) {
for (ClassMappingEnum cme : ClassMappingEnum.values()) {
if (cme.typeDes.equals(compare)) {
return cme;
}
}
return UNKNOWN;
}
}
class EchoExpression<T> {
private String someString;
private Class<T> someClass;
public EchoExpression(String someString, Class<T> someClass) {
super();
this.someString = someString;
this.someClass = someClass;
}
public String getSomeString() {
return someString;
}
public void setSomeString(String someString) {
this.someString = someString;
}
public Class<T> getSomeClass() {
return someClass;
}
public void setSomeClass(Class<T> someClass) {
this.someClass = someClass;
}
}
class OutExpression {
private String someString;
public OutExpression(String someString) {
super();
this.someString = someString;
}
public String getSomeString() {
return someString;
}
public void setSomeString(String someString) {
this.someString = someString;
}
}
If you can modify the classes so both constructor has the same signature (accepts the same number/type of arguments in the same order), you could do
Constructor constructor = aClass.getConstructor(new Class[]{String.class,Class.class});
Object object= constructor.newInstance(expression, Boolean.class);
for both classes.
This of course means that the class that right now do not need the extra parameter, will have to ignore the passed-in one it was not using before after the change
UPDATE: Here is a possible way of implementing the idea using Factory classes:
public interface ObjectFactory
{
Object create(String expr, Class cls);
}
public class EchoExpressionFactory implements ObjectFactory
{
public EchoExpression create(String expr, Class cls)
{
return new EchoExpression(expr, cls);
}
}
public class OutExpressionFactory implements ObjectFactory
{
public OutExpression create(String expr, Class cls)
{
return new OutExpression(expr);
}
}
public class ExampleFactory {
private static HashMap<String,ObjectFactory> hmap = new HashMap<String,ObjectFactory>();
static
{
hmap.put("echo", new EchoExpressionFactory());
hmap.put("Out", new OutExpressionFactory());
}
public void getExpo(String key,String expression)
{
ObjectFactory factory = map.get(key);
//Constructor implementation for Expression
Object object = factory.create(expression);
Object object= constructor.newInstance(expression, Boolean.class);
return;
}
}
I have the following code
public abstract class Event {
public void fire(Object... args) {
// tell the event handler that if there are free resources it should call
// doEventStuff(args)
}
// this is not correct, but I basically want to be able to define a generic
// return type and be able to pass generic arguments. (T... args) would also
// be ok
public abstract <T, V> V doEventStuff(T args);
}
public class A extends Event {
// This is what I want to do
#Overide
public String doEventStuff(String str) {
if(str == "foo") {
return "bar";
} else {
return "fail";
}
}
}
somewhere() {
EventHandler eh = new EventHandler();
Event a = new A();
eh.add(a);
System.out.println(a.fire("foo")); //output is bar
}
However I don't know how to do this, as I cannot override doEventStuff with something specific.
Does anyone know how to do this?
It's not really clear what you're trying to do, but perhaps you just need to make Event itself generic:
public abstract class Event<T, V>
{
public abstract V doEventStuff(T args);
}
public class A extends Event<String, String>
{
#Override public String doEventStuff(String str)
{
...
}
}
You're using generics but you are not providing a binding.
public abstract class Event<I, O> { // <-- I is input O is Output
public abstract O doEventStuff(I args);
}
public class A extends Event<String, String> { // <-- binding in the impl.
#Override
public String doEventStuff(String str) {
}
}
Or simpler with only one generic binding...
public abstract class Event<T> { // <-- only one provided
public abstract T doEventStuff(T args);
}
public class A extends Event<String> { // <-- binding the impl.
#Override
public String doEventStuff(String str) {
}
}