Is there a way to implement something like
List<Class<? implements MyInterface>> ClassList = new ArrayList<Class<? implements MyInterface>>();
my goal is to create a hashmap from that list, where the keys are the toString methods of the class (defined in MyInterface) and the values are the classes itself. The toString method of every object of this class returns the same result. This way I could create Instances of the classes using the map by searching the right strings.
thank you for trying to help,
greetings
List<Class<? implements MyInterface>> ClassList = new ArrayList<Class<? implements MyInterface>>();
should be
List<Class<? extends MyInterface>> ClassList = new ArrayList<Class<? extends MyInterface>>();
there is no implements keyword in the world of generics. if you want a type parameter that implements an interface , use the extends keyword to represent it.
Since you seem interested by the way I explained, here is a quick implementation, to verify it can be done...
import java.util.ArrayList;
import java.util.List;
enum NumberClass
{
ONE("One"),
TWO("Two"),
THREE("Three");
private final String className;
NumberClass(String name)
{
className = name;
}
String getName()
{
return className;
}
}
public class Test
{
public static void main(String[] args)
{
List<NumberClass> numbers = new ArrayList<NumberClass>();
numbers.add(NumberClass.ONE);
numbers.add(NumberClass.THREE);
numbers.add(NumberClass.TWO);
numbers.add(NumberClass.ONE);
numbers.add(NumberClass.THREE);
numbers.add(NumberClass.ONE);
numbers.add(NumberClass.TWO);
SomeNumber[] nbs = new SomeNumber[numbers.size()];
int i = 0;
for (NumberClass nbC : numbers)
{
SomeNumber nb;
try
{
nb = (SomeNumber) Class.forName(nbC.getName()).newInstance ();
nbs[i++] = nb;
}
// Cleanly handle them!
catch (InstantiationException e) { System.out.println(e); }
catch (IllegalAccessException e) { System.out.println(e); }
catch (ClassNotFoundException e) { System.out.println(e); }
}
for (SomeNumber sn : nbs)
{
System.out.println(sn.getClass().getName() + " " + sn.getValue());
}
}
}
// The following must be in their own files, of course
public interface SomeNumber
{
int getValue();
}
public class One implements SomeNumber
{
public int getValue() { return 1; }
}
public class Two implements SomeNumber
{
public int getValue() { return 2; }
}
public class Three implements SomeNumber
{
public int getValue() { return 3; }
}
If it doesn't answer your question, consider it as educational material, I hope. :-)
Related
I have a program that can print a pizza with decorators. I have an interface:
public interface PizzaPie{
String top();
}
And an implementation of the interface
public class PizzaPieImplementation implements PizzaPie{
#Override
public String top() {
return "Pie of pizza";
}
}
And an abstract class that implements it with the same object.
public abstract class PizzaTopper implements PizzaPie{
private PizzaPie pizza;
#Override
public String top() {
return pizza.top();
}
}
And I have several decorator classes, such as
public class Onions extends PizzaTopper{
public Onions(PizzaPie pizza) {
super(pizza);
}
public String top() {
return super.top() + topWithOnions();
}
private String topWithOnions() {
return " with onions";
}
And similar classes for peppers, pepperoni, anchovies, pineapple, etc.
I have a list as follows:
List<String> toppings = {onions, pineapple};
Is there a way to take each topping from the toppings list, and use that to create a new pizza with those toppings, to return something like:
Pie of pizza with onions with pineapple
The method would look something like this:
public PizzaPie CreatePizzaWithUserInput(List<String> toppings) {
//code
}
And ultimately it would create code that looks like this:
PizzaPie pizza1 = new Onion(new Pineapple(new PizzaPieImplementation()));
In theory this can be done with a lot of ugly if statements but I'm wondering if there's a quicker way of doing it.
You can use Java Reflection to achieve this.
Here we build our factory with the different possibilities of toppings, then we create a Pizza using createPizzaWithUserInput.
In this example we built a pizza with 3 of the four possible toppings.
Notice that to add a new Topping possibility you just extends PizzaTopper and add it on the toppingOptions on the PizzaFactory instantiation.
import java.util.List;
import java.util.LinkedList;
class Main {
public static void main(String[] args) {
// Possibilities
PizzaFactory pizzaFactory = new PizzaFactory(Onions.class, Bacon.class, Olives.class, Tomatos.class);
// User input
List<String> toppings = new LinkedList<String>();
toppings.add("onions");
toppings.add("olives");
toppings.add("bacon");
try{
PizzaPie pizza = pizzaFactory.createPizzaWithUserInput(toppings);
System.out.println(pizza.top());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here we have the PizzaFactory. We use the class' name to do the matching with the topping option, but you can customize it if you want (to match also "onion"/"onions" or "tomato"/"tomatos" for instance).
import java.util.List;
import java.util.Arrays;
import java.lang.reflect.*;
public class PizzaFactory {
List<Class<? extends PizzaTopper>> toppingOptions;
public PizzaFactory(Class<? extends PizzaTopper>... toppingOptions) {
this.toppingOptions = Arrays.asList(toppingOptions);
}
public PizzaPie createPizzaWithUserInput(List<String> toppings) throws NoSuchMethodException, InstantiationException, IllegalAccessException,InvocationTargetException {
PizzaPie pizza = new PizzaPieImplementation();
for(String toppingName : toppings) {
for(Class<? extends PizzaTopper> top : toppingOptions) {
if(top.getName().toLowerCase().equals(toppingName.toLowerCase())) {
Constructor<? extends PizzaPie> constructor = top.getConstructor(PizzaPie.class);
pizza = constructor.newInstance(pizza);
}
}
}
return pizza;
}
}
Here we have the interface PizzaPie:
public interface PizzaPie{
String top();
}
And its implementation.
public class PizzaPieImplementation implements PizzaPie{
#Override
public String top() {
return "Pie of pizza";
}
}
The decorator class.
public abstract class PizzaTopper implements PizzaPie{
private PizzaPie pizza;
protected PizzaTopper(PizzaPie pizza) {
this.pizza = pizza;
}
#Override
public String top() {
return pizza.top();
}
}
Tomatos topping.
public class Tomatos extends PizzaTopper{
public Tomatos(PizzaPie pizza) {
super(pizza);
}
public String top() {
return super.top() + topWithOnions();
}
private String topWithOnions() {
return " with tomatos";
}
}
Onions topping.
public class Onions extends PizzaTopper{
public Onions(PizzaPie pizza) {
super(pizza);
}
public String top() {
return super.top() + topWithOnions();
}
private String topWithOnions() {
return " with onions";
}
}
Olives topping
public class Olives extends PizzaTopper{
public Olives(PizzaPie pizza) {
super(pizza);
}
public String top() {
return super.top() + topWithOnions();
}
private String topWithOnions() {
return " with olives";
}
}
Bacon topping.
public class Bacon extends PizzaTopper{
public Bacon(PizzaPie pizza) {
super(pizza);
}
public String top() {
return super.top() + topWithOnions();
}
private String topWithOnions() {
return " with bacon";
}
}
You could just make the member variable stored in PizzaTopper an array, and its constructor accept (PizzaPie... pizzas). Then, you could pass in an array of pizzas/toppings (anything implementing PizzaPie) and PizzaTopper.top() could return a runtime-generated concatenation of all of the PizzaPies' top() results.
I am writing a java (processing) library for unexperienced students, and am looking for the best architecture for implementing it.
Initialization of an object should be as close as possible to this:
myObject = new General("type1");
Such that myObject will become an instance of Type1 which extends General:
class General {
public General() {}
}
class Type1 extends General {
public Type1() {}
}
class Type2 extends General {
public Type1() {}
}
As far as I know, this isn't possible (choosing between extended classes during initialization), but I'm looking for the closest solution possible.
So far, my best solution is to make a static initializer inside General:
class General {
...
static General init (String type) {
General temp;
if (type.equals("type1") {
temp = new Type1();
}
...
return temp;
}
and the initialization is:
General myObject;
myObject = General.init("type1");
This is far from ideal...
thanks.
you can make a factory class that manages initialization.
instead of doing it inside the parent.
// Empty vocabulary of actual object
public interface IPerson
{
string GetName();
}
public class Villager : IPerson
{
public string GetName()
{
return "Village Person";
}
}
public class CityPerson : IPerson
{
public string GetName()
{
return "City Person";
}
}
public enum PersonType
{
Rural,
Urban
}
/// <summary>
/// Implementation of Factory - Used to create objects.
/// </summary>
public class Factory
{
public IPerson GetPerson(PersonType type)
{
switch (type)
{
case PersonType.Rural:
return new Villager();
case PersonType.Urban:
return new CityPerson();
default:
throw new NotSupportedException();
}
}
}
The State design pattern can be a solution here. Rather than the constructor argument changing the type of the object (which isn't possible) it can set a field of the object, to make it behave as if its type is different.
package stackoverflow.questions;
public class Main {
private interface MyInterface {
String foo();
int bar();
}
private static class Type1 implements MyInterface {
#Override public String foo() { return "lorem ipsum "; }
#Override public int bar() { return 6; }
}
private static class Type2 implements MyInterface {
#Override public String foo() { return "dolor sit amet"; }
#Override public int bar() { return 7; }
}
public static class General {
private final MyInterface type;
public General(String type) {
try {
this.type = (MyInterface) Class
.forName("stackoverflow.questions.Main$" + type)
.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new IllegalArgumentException("Invalid type: " + type);
}
}
public String method1() { return type.foo(); }
public int method2() { return type.bar(); }
}
public static void main(String... args) {
General one = new General("Type1");
General two = new General("Type2");
System.out.println(one.method1() + two.method1());
System.out.println(one.method2() * two.method2());
}
}
I'm struggling to make a mapping from class B to any subclass of A. See code below. It seems it is not possible with ModelMapper, since it ignores converter if it is not exact match. Could you recommend some similar library that is capable of this? Or any recommendation how to do similar behavior, without specifying all possible subclasses explicitly. Thanks a lot.
package com.randakm.p2plibrary.service.main;
import org.modelmapper.Converter;
import org.modelmapper.ModelMapper;
import org.modelmapper.spi.MappingContext;
public class ServiceMain {
/**
* #param args
*/
public static void main(String[] args) {
ModelMapper mapper = new ModelMapper();
mapper.addConverter(new B2AConverter());
B b = new B();
b.b = "some value";
A a = mapper.map(b, AA.class);
System.out.println("a: "+a.a); // I expect this to have the value from b
}
}
abstract class A {
String a;
}
class AA extends A {
String aa;
}
class AAA extends A {
String aaa;
}
class B {
String b;
}
class B2AConverter implements Converter<B, A> {
#Override
public A convert(MappingContext<B, A> context) {
B b = context.getSource();
A a;
try {
a = context.getDestinationType().newInstance();
a.a = b.b;
return a;
} catch (InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
I have to handle two classes with identical methods but they don't implement the same interface, nor do they extend the same superclass. I'm not able / not allowed to change this classes and I don't construct instances of this classes I only get objects of this.
What is the best way to avoid lots of code duplication?
One of the class:
package faa;
public class SomethingA {
private String valueOne = null;
private String valueTwo = null;
public String getValueOne() { return valueOne; }
public void setValueOne(String valueOne) { this.valueOne = valueOne; }
public String getValueTwo() { return valueTwo; }
public void setValueTwo(String valueTwo) { this.valueTwo = valueTwo; }
}
And the other...
package foo;
public class SomethingB {
private String valueOne;
private String valueTwo;
public String getValueOne() { return valueOne; }
public void setValueOne(String valueOne) { this.valueOne = valueOne; }
public String getValueTwo() { return valueTwo; }
public void setValueTwo(String valueTwo) { this.valueTwo = valueTwo; }
}
(In reality these classes are larger)
My only idea is now to create a wrapper class in this was:
public class SomethingWrapper {
private SomethingA someA;
private SomethingB someB;
public SomethingWrapper(SomethingA someA) {
//null check..
this.someA = someA;
}
public SomethingWrapper(SomethingB someB) {
//null check..
this.someB = someB;
}
public String getValueOne() {
if (this.someA != null) {
return this.someA.getValueOne();
} else {
return this.someB.getValueOne();
}
}
public void setValueOne(String valueOne) {
if (this.someA != null) {
this.someA.setValueOne(valueOne);
} else {
this.someB.setValueOne(valueOne);
}
}
public String getValueTwo() {
if (this.someA != null) {
return this.someA.getValueTwo();
} else {
return this.someB.getValueTwo();
}
}
public void setValueTwo(String valueTwo) {
if (this.someA != null) {
this.someA.setValueTwo(valueTwo);
} else {
this.someB.setValueTwo(valueTwo);
}
}
}
But I'm not realy satisfied with this solution. Is there any better / more elegant way to solve this problem?
A better solution would be to create an interface to represent the unified interface to both classes, then to write two classes implementing the interface, one that wraps an A, and another that wraps a B:
public interface SomethingWrapper {
public String getValueOne();
public void setValueOne(String valueOne);
public String getValueTwo();
public void setValueTwo(String valueTwo);
};
public class SomethingAWrapper implements SomethingWrapper {
private SomethingA someA;
public SomethingWrapper(SomethingA someA) {
this.someA = someA;
}
public String getValueOne() {
return this.someA.getValueOne();
}
public void setValueOne(String valueOne) {
this.someA.setValueOne(valueOne);
}
public String getValueTwo() {
return this.someA.getValueTwo();
}
public void setValueTwo(String valueTwo) {
this.someA.setValueTwo(valueTwo);
}
};
and then another class just like it for SomethingBWrapper.
There, a duck-typed solution. This will accept any object with valueOne, valueTwo properties and is trivially extensible to further props.
public class Wrapper
{
private final Object wrapped;
private final Map<String, Method> methods = new HashMap<String, Method>();
public Wrapper(Object w) {
wrapped = w;
try {
final Class<?> c = w.getClass();
for (String propName : new String[] { "ValueOne", "ValueTwo" }) {
final String getter = "get" + propName, setter = "set" + propName;
methods.put(getter, c.getMethod(getter));
methods.put(setter, c.getMethod(setter, String.class));
}
} catch (Exception e) { throw new RuntimeException(e); }
}
public String getValueOne() {
try { return (String)methods.get("getValueOne").invoke(wrapped); }
catch (Exception e) { throw new RuntimeException(e); }
}
public void setValueOne(String v) {
try { methods.get("setValueOne").invoke(wrapped, v); }
catch (Exception e) { throw new RuntimeException(e); }
}
public String getValueTwo() {
try { return (String)methods.get("getValueTwo").invoke(wrapped); }
catch (Exception e) { throw new RuntimeException(e); }
}
public void setValueTwo(String v) {
try { methods.get("setValueTwo").invoke(wrapped, v); }
catch (Exception e) { throw new RuntimeException(e); }
}
}
You can use a dynamic proxy to create a "bridge" between an interface you define and the classes that conform but do not implement your interface.
It all starts with an interface:
interface Something {
public String getValueOne();
public void setValueOne(String valueOne);
public String getValueTwo();
public void setValueTwo(String valueTwo);
}
Now you need an InvocationHandler, that will just forward calls to the method that matches the interface method called:
class ForwardInvocationHandler implements InvocationHandler {
private final Object wrapped;
public ForwardInvocationHandler(Object wrapped) {
this.wrapped = wrapped;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Method match = wrapped.getClass().getMethod(method.getName(), method.getParameterTypes());
return match.invoke(wrapped, args);
}
}
Then you can create your proxy (put it in a factory for easier usage):
SomethingA a = new SomethingA();
a.setValueOne("Um");
Something s = (Something)Proxy.newProxyInstance(
Something.class.getClassLoader(),
new Class[] { Something.class },
new ForwardInvocationHandler(a));
System.out.println(s.getValueOne()); // prints: Um
Another option is simpler but requires you to subclass each class and implement the created interface, simply like this:
class SomethingAImpl extends SomethingA implements Something {}
class SomethingBImpl extends SomethingB implements Something {}
(Note: you also need to create any non-default constructors)
Now use the subclasses instead of the superclasses, and refer to them through the interface:
Something o = new SomethingAImpl(); // o can also refer to a SomethingBImpl
o.setValueOne("Uno");
System.out.println(o.getValueOne()); // prints: Uno
i think your original wrapper class is the most viable option...however it can be done using reflection, your real problem is that the application is a mess...and reflection is might not be the method you are looking for
i've another proposal, which might be help: create a wrapper class which has specific functions for every type of classes...it mostly copypaste, but it forces you to use the typed thing as a parameter
class X{
public int asd() {return 0;}
}
class Y{
public int asd() {return 1;}
}
class H{
public int asd(X a){
return a.asd();
}
public int asd(Y a){
return a.asd();
}
}
usage:
System.out.println("asd"+h.asd(x));
System.out.println("asd"+h.asd(y));
i would like to note that an interface can be implemented by the ancestor too, if you are creating these classes - but just can't modify it's source, then you can still overload them from outside:
public interface II{
public int asd();
}
class XI extends X implements II{
}
class YI extends Y implements II{
}
usage:
II a=new XI();
System.out.println("asd"+a.asd());
You probably can exploit a facade along with the reflection - In my opinion it streamlines the way you access the legacy and is scalable too !
class facade{
public static getSomething(Object AorB){
Class c = AorB.getClass();
Method m = c.getMethod("getValueOne");
m.invoke(AorB);
}
...
}
I wrote a class to encapsulate the logging framework API's. Unfortunately, it's too long to put in this box.
The program is part of the project at http://www.github.com/bradleyross/tutorials with the documentation at http://bradleyross.github.io/tutorials. The code for the class bradleyross.library.helpers.ExceptionHelper in the module tutorials-common is at https://github.com/BradleyRoss/tutorials/blob/master/tutorials-common/src/main/java/bradleyross/library/helpers/ExceptionHelper.java.
The idea is that I can have the additional code that I want to make the exception statements more useful and I won't have to repeat them for each logging framework. The wrapper isn't where you eliminate code duplication. The elimination of code duplication is in not having to write multiple versions of the code that calls the wrapper and the underlying classes. See https://bradleyaross.wordpress.com/2016/05/05/java-logging-frameworks/
The class bradleyross.helpers.GenericPrinter is another wrapper that enables you to write code that works with both the PrintStream, PrintWriter, and StringWriter classes and interfaces.
Sorry for the cryptic title, but this is difficult to explain. The general rule is that I need a lazy loader that will give me N instances of a bound wildcard type. I'm calling the lazy loader a storage unit.
import java.util.ArrayList;
import java.util.List;
public class StorageUnit<T extends MyInterface> implements Storable<T> {
private int count;
public StorageUnit(int count) {
this.count = count;
}
private List<T> storables = new ArrayList<T>();
public List<T> getInstances(Class<T> c) {
try {
if (storables.size() == 0) {
for (int i = 0; i < count; i++) {
storables.add(c.newInstance());
}
} else {
return storables;
}
}catch (IllegalAccessException illegalAccessException) {
illegalAccessException.printStackTrace();
} catch (InstantiationException instantiationException) {
instantiationException.printStackTrace();
}
return storables;
}
}
Elsewhere in my application I have another class that has a reference to several of these storage units. I need to get instances of the storage unit type, and then I will do something with that type.
import java.util.ArrayList;
import java.util.List;
public class MyStorageUnitContainer {
private List<StorageUnit<? extends MyInterface>> storageUnits;
public MyStorageUnitContainer(List<StorageUnit<? extends MyInterface>> storageUnits) {
this.storageUnits = storageUnits;
}
public List<StorageUnit<? extends MyInterface>> getInstances() {
List<StorageUnit<? extends MyInterface>> instances = new ArrayList<StorageUnit<? extends MyInterface>>();
for (StorageUnit<? extends MyInterface> storageUnit : storageUnits) {
storageUnit.getInstances(/* I can't get the bound wildcard... */);
// Now loop through those instances and do something with them...
}
return instances;
}
}
That code sucks, so the best analogy I can think of is an actual storage unit container. That storage unit container has several individual storage units (think boxes). Each one of those boxes contains items of a certain type (think baseball cards). I know that a box contains 100 baseball cards, but until I open the box I don't know anything about the details of each baseball card. I'm basically trying to treat each box as a lazy loader. Opening the box loads N implementations if they don't exist already.
Paulo is correct, and (also as per Paulo's answer), I often just pass a class object into a constructor to get around this problem. It allows the getInstances() method to appear as you would like it - ie without parameters. Internally, the instance keeps a reference to the generic class so it can call newInstance() on it.
This code illustrates this using your example. I have tested this an it executes OK.
import java.util.ArrayList;
import java.util.List;
public class Sandbox
{
static interface MyInterface
{
}
static interface Storable<T>
{
List<T> getInstances();
};
static abstract class MyStorableImpl implements MyInterface
{
#Override
public String toString()
{
return "I'm a " + getClass() + " with hashcode " + hashCode();
}
}
static class MyStorable1 extends MyStorableImpl
{
}
static class MyStorable2 extends MyStorableImpl
{
}
static class StorageUnit<T extends MyInterface> implements Storable<T>
{
private final int count;
private final Class<T> clazz;
public StorageUnit(Class<T> clazz, int count)
{
this.count = count;
this.clazz = clazz;
}
private List<T> storables = new ArrayList<T>();
public List<T> getInstances()
{
try
{
if (storables.size() == 0)
{
for (int i = 0; i < count; i++)
{
storables.add(clazz.newInstance());
}
}
else
{
return storables;
}
}
catch (IllegalAccessException illegalAccessException)
{
illegalAccessException.printStackTrace();
}
catch (InstantiationException instantiationException)
{
instantiationException.printStackTrace();
}
return storables;
}
}
static class MyStorageUnitContainer
{
private List<StorageUnit<? extends MyInterface>> storageUnits;
public MyStorageUnitContainer(List<StorageUnit<? extends MyInterface>> storageUnits)
{
this.storageUnits = storageUnits;
}
public List<MyInterface> getAllInstances()
{
List<MyInterface> instances = new ArrayList<MyInterface>();
for (StorageUnit<? extends MyInterface> storageUnit : storageUnits)
{
List<? extends MyInterface> list = storageUnit.getInstances();
instances.addAll(list);
}
return instances;
}
}
public static void main(String[] args)
{
StorageUnit<? extends MyInterface> box1 = new StorageUnit<MyStorable1>(MyStorable1.class, 2);
StorageUnit<? extends MyInterface> box2 = new StorageUnit<MyStorable2>(MyStorable2.class, 3);
List<StorageUnit<? extends MyInterface>> boxes = new ArrayList<Sandbox.StorageUnit<? extends MyInterface>>();
boxes.add(box1);
boxes.add(box2);
MyStorageUnitContainer container = new MyStorageUnitContainer(boxes);
List<MyInterface> allInstances = container.getAllInstances();
for (MyInterface myInterface : allInstances)
{
System.out.println(myInterface.toString());
}
}
}
With Java Generics you can't get from a type variable (or even less from a wildcard) to an actual class object.
The reason is the way generics are implemented: by type erasure. This means that actually on run-time your generic types are not there anymore, they are erased to raw types. Only the compiler checks that you are using the right types at the right place.
In your case, the StorageUnit<T> objects do not contain any information about the T used here, if you don't give them a class object of the right type. They also all have the same class object.
So, the best bet here would be to give the StorageUnit objects a class object of their parameter class in the constructor, then the getInstances() method would not need to take it. Of course, this only shifts the problem on having to have a class object to another location, but somewhere it is necessary.