This is an educational question that relates to a hobby project. Project Spring Boot MVC/REST app.
I would like to retain the flexibility to be able to create multiple implementations of Service and have list return a list of objects, depending on what the implementation requires.
I appreciate I could create some inheritance/implementation hierarchy to define the kinds of objects of which T could encompass. My problem with both of those answers is that some use cases for Service involve me needing to return Lists of Java Standard Lib types - types I would rather not inherit/extend/implement for my own custom classes, which I would prefer be kept as lean as possible.
import java.util.List;
interface Service {
<T> List<T> list(String location, MyEnums.mediaType type );
}
class MyEnums {
enum mediaType {
IMAGE, VIDEO, AUDIO
}
}
class LocalService implements Service {
public List<MyConcreteClass> list(String location, MyEnums.mediaType type ) {
List<MyConcreteClass> list = null;
list.add(new MyConcreteClass(1, "foo", new byte[0]));
return list;
}
}
class MyConcreteClass implements Comparable<MyConcreteClass> {
private final long id;
private final String name;
private final byte[] data;
public MyConcreteClass(long id, String name, byte[] data) {
this.id = id;
this.name = name;
this.data = data;
}
#Override
public int compareTo(MyConcreteClass o) {
return this.name.compareTo(o.name);
}
// Other methods omitted for brevity
}
The above code is only a simplified example of the actual app code - which compiles and runs without any (known) runtime bugs. However I get the compiler warning:
Unchecked overriding: return type requires unchecked conversion.
The presence of a warning makes sense to me - code consuming the Service interface/API could break at runtime if the return type requirement in the calling code is incompatible with the implementation, whereas the error would be caught at compile if I had a more specific List<> defined in the interface.
This would, of course, not be an issue if I had to wire in a concrete implementation into the code consuming my service - however the joys of Spring!
What am I doing wrong? How can I fix this? Are generics the right way to achieve a polymorphic list() function in my case?
You can eliminate the unchecked cast by declaring the interface itself with a type parameter (instead of the method). Like this:
interface Service<T> {
List<T> list(String location, String type );
}
class LocalService implements Service<MyConcreteClass> {
#Override
public List<MyConcreteClass> list(String location, String type ) {
// Some logic to retrieve, alter and return a list
return null;
}
}
class StringService implements Service<String> {
#Override
public List<String> list(String location, String type) {
// TODO Auto-generated method stub
return null;
}
}
class MyConcreteClass {
/// ...
}
(I changed a couple of things to make it compile, not relevant to the answer).
I have seen this which is pretty nice solution if i had a string instead of integer, but in case all i have is the specific enum's class object and an integer, how to do i get the specific enum constant instance?
Relying on the ordinal value of Java enum constants is poor practice -- it's too easy to accidentally reorder them, which would then break your code. The better solution is to simply provide your own integer that you can use instead:
public enum MyThing {
FOO(1),
BAR(2),
BAZ(3);
private final int thingId;
private MyThing(int thingId) {
this.thingId = thingId;
}
public int getThingId() {
return thingId;
}
}
Then whenever you want to get the thingId from a MyThing, just call the getThingId() method:
void doSomething(MyThing thing) {
System.out.printf("Got MyThing object %s with ID %d\n",
thing.name(), thing.getThingId());
}
If you want to be able to look up a MyThing by its thingId, you can build a lookup table yourself and store it in a static final field:
private static final Map<Integer, MyThing> LOOKUP
= createLookupMap();
private static Map<Integer, MyThing> createLookupMap() {
Map<Integer, MyThing> lookupMap = new HashMap<>();
for (MyThing thing : MyThing.values()) {
lookupMap.put(thing.getThingId(), thing);
}
return Collections.unmodifiableMap(lookupMap);
}
public static MyThing getThingById(int thingId) {
MyThing result = LOOKUP.get(thingId);
if (result == null) {
throw new IllegalArgumentException(
"This is not a valid thingId: " + thingId);
}
return result;
}
If you end up having a lot of enum classes and you want to do a similar thing with each of them, you can define an interface for that:
public interface Identifiable {
int getId();
}
And then make your enum implement that interface:
public enum MyThing implements Identifiable {
...
#Override
public int getId() {
return thingId;
}
}
And then you could build a reusable mechanism for looking up an Identifiable object based on its ID.
seem to have found the answer :
((Class<? extends Enum>)clazz).getEnumConstants()[index]
although for any-one looking for that, you should consider following #Daniel Pryden answer as most likely that using this in most use cases i can think of is bad practice.
I'm new to java and Generics so please bear with me. I don't even know if this is possible. I've looked around and although there seem to be a few posts about this here and there I haven't found one that addresses my specific case clearly enough for me to understand what to do.
I basically have a static method in the parent class and would like it to return various types based on which child calls it. The trick here is that said child class that is returned also needs to be instantiated within the method.
Here's what I mean:
public class Parent {
public String value;
public Parent(String value)
{
this.value = value;
}
public static <T extends Parent> T load(DataStorage data, String key)
{
T inst = new ???(data.getValue(key));
return inst;
}
}
public class Child extends Parent {
}
Child child = Child.load(dataStore, "key"); // random dataStore instance
I'm not sure where to go from here. What do I use in place of ??? which should be whichever child (or Parent) runs the load() ? Do I need to also do something along the lines of Child.<Child>load()?
I'm open to alternative designs if you feel I'm mistaking in trying to do things like this. I don't like the idea of having to play around with Reflection in this situation (feels a little hacky)
Thanks in advance, I really appreciate it.
I guess what you want would be possible if Java didn't have type erasure and had 'constructor with parameter constraint' for generic types(like .net, but it has constraint for parameterless constructors only).
Maybe those two suits your needs:
If type of Child based on some selection criteria(e.g. an enumaration) I would go with a factory pattern like:
public class ParentFactory {
Parent create(SomeEnum t, DataStore dataStore, String key) {
switch (t) {
case SomeEnum.Child1Related:
return new Child1(dataStore.get(key));
...
}
}
}
But if creation is completely irrelevant(which is not in most cases), you can just define an init method in Parent and have initializer code there:
abstract class Parent {
String value;
Parent() {}
protected void init(String s) { this.value = s; }
static <T extends Parent> void initialize(DataStore data, String key, T t) {
t.init(data.getValue(key));
}
Child c = new Child();
Parent.init(dataStore, key, c);
You can make init method as private if you want to prohibit childs to intercept that call.
Honestly, I favor first one much more. Second one is a little ugly :)
It sounds like the thing you're looking for is a strongly-typed key object, which can associate a string with the corresponding child type. What I've done in the past is simply write a class for this key type.
Assuming your datastore looks something like this:
public interface DataStore {
DataItem get(String key);
}
And your various child classes look like this:
public final class Child1 extends Parent {
public Child1(DataItem dataItem) {
...
}
...
}
Your Key type could look like this:
/**
* Represents a way to construct an object from a {#link DataItem}.
*
* #param <T> the type of the object to construct.
*/
public final class Key<T extends Parent> {
private final String key;
// Assuming Java 8 Function. If you're using Java 7 or older,
// you can define your own Function interface similarly.
private final Function<DataItem, T> factoryFunction;
public Key(String key, Function<String, T> factoryFunction) {
this.key = checkNotNull(key);
this.factoryFunction = checkNotNull(factoryFunction);
}
public String key() {
return this.key;
}
public T constructFrom(DataItem dataItem) {
if (!key.equals(dataItem.getKey())) {
throw new IllegalStateException(
"DataItem is not valid for key " + key);
}
return factoryFunction.apply(dataItem);
}
}
Then you'll probably want a collection of well-known keys:
/** Well-known {#link Key} instances. */
public final class Keys {
private Keys() {} // static class
/** Key for {#link Child1}. */
public static final Key<Child1> FIRST_CHILD
= new Key<>("child1", Child1::new);
/** Key for {#link Child2}. */
public static final Key<Child2> SECOND_CHILD
= new Key<>("child2", Child2::new);
// etc.
}
Then you can define classes that work with these strongly-typed key instances:
public final class Loader {
private final DataStore dataStore;
public Loader(DataStore dataStore) {
this.dataStore = checkNotNull(dataStore);
}
public <T extends Parent> T load(Key<T> dataKey) {
return key.constructFrom(dataStore.get(dataKey.key()));
}
...
}
Note that this example still works even if you don't have Java 8 -- you'll just need to use an anonymous inline class to construct the child, rather than a lambda expression:
public static final Key<Child1> FIRST_CHILD =
new Key<Child1>("child1", new Function<DataItem, Child1>() {
#Override public Child1 apply(DataItem dataItem) {
return new Child1(dataItem);
}
});
You could of course use reflection for this part if you want, but manually writing the supplier functions will be faster. (Or, if you want the best of both worlds, you could use something like cglib's FastClass.) If you wanted to, you could also make the Key class abstract, so that you would subclass it and override a factory method rather than using a Function.
If you want to, you can merge the Loader type into your Parent class, but I wouldn't, since I think that would violate the Single Responsibility Principle -- typically you want the job of loading domain objects from storage to be separate from the domain objects themselves.
Hopefully that helps!
I have one supertype defined as:
public abstract class AType<T> {
....
private T value;
private T mask;
public T getValue() {
if (isMasking())
return null;
return this.value;
}
public void setValue(T value) {
if (value == null)
throw new IllegalArgumentException("Value is mandatory.");
this.value = value;
}
protected T getMask() {
if (!isMasking())
return null;
return this.mask;
}
protected void setMask(T mask) {
if (mask == null)
throw new IllegalArgumentException("Mask is mandatory.");
this.setMasking(true);
this.mask = mask;
}
...
}
and few subtypes like:
public class SpecType extends AType<Integer> {
...
}
these sub types specifies the unknown parameter.... i have more f.e. IPv4, Long, and so on
now i need to somehow in runtime do a dynamic cast...
i have these classes defined in enum like this:
public enum Type {
SOME_TYPE(new TypeID(0, (short) 0), OFMU16.class,
new Instantiable<AType<?>>() {
#Override
public SpecType instantiate() {
return new SpecType(new OFMatchTypeIdentifier(0, (short) 0));
}
}),...;
...
public Class<? extends AType<?>> toClass() {
return this.clazz;
}
...
}
I want do something like:
AType<?> type = SOME_TYPE.newInstance(); //this works
SOME_TYPE.toClass().cast(type).setValue(10); //this don't work
so I have to do it statically:
((SpecType) type).setValue(10);
Everything would be OK, but the user of this module will not want to look in enum and cast manually every time. This will probably make mistakes and spend a lot of time with debugging :/....
My question is how can I refactor this or how do I define structure of inheritance to allow user to cast dynamically? Is it possible?
Edit:
I am parsing packets from network. There is a lot types which differs in Vendor Type identifier and type of Value/Mask - these fields are all constant for every this combination, so i has defined it as enum constants. F.e. 20 have different only TypeID but same VendorID and all of them can be represented as Integer, next 10 differ in VendorID And TypeID but all of them can be represented as Short and so on.
It's still not clear why you should have to cast at all. As soon as SOME_TYPE is written into your sourcecode OR the type of set setValue method is hardcoded (in your example int or Integer) you don't need runtime checking - you need compile time checking.
So I suppose the following snippet is how your API users should code:
public class TypeTest {
public static void main(String[] args) {
AType<Integer> type0 = Types.SOME_TYPE_0.instantiate();
type0.setValue(10);
AType<String> type1 = Types.SOME_TYPE_1.instantiate();
type1.setValue("foo");
}
}
I have stripped down your example to the bare minimum which is required to understand the Generics part:
abstract class AType<T> {
private T value;
// standard getter/setter
public T getValue() { return this.value; }
public void setValue(T value) { this.value = value; }
}
class SpecTypeInt extends AType<Integer> {
}
class SpecTypeString extends AType<String> {
}
interface Instantiable<T> {
T instantiate();
}
The key part is: Don't use an enum, because an enum cannot have type parameters. You can use a plain interface instead like the next snippet. Each reference in the interface points to a factory. Each factory knows a) the abstract type and b) the concrete type. To make Generics happy you have to glue a) and b) together with ? extends X.
interface Types {
Instantiable<? extends AType<Integer>> SOME_TYPE_0 = new Instantiable<SpecTypeInt>() {
#Override
public SpecTypeInt instantiate() {
return new SpecTypeInt();
}
};
Instantiable<? extends AType<String>> SOME_TYPE_1 = new Instantiable<SpecTypeString>() {
#Override
public SpecTypeString instantiate() {
return new SpecTypeString();
}
} ;
}
Cleanup: Must your user look into the interface: Yes, he must in any case, because he must know which is the appropriate type for setValue 1. NO solution can circumvent this. Although Eclipse might help you and your users a little bit: In main just type Types.SOME_TYPE_1.instantiate(); then go to the start of the line, hit Ctrl2 + L ("Assign to loccal variable") and Eclipse replaces the AType<String> instantiate = part for you.
1If your users don't know the right type for the setValue method, then you are asking the wrong question. In that case you should have asked something like "How to design a Generic safe conversion facility?".
Maybe using a setValue method like this:
public void setValue(Object value) {
if (value == null)
throw new IllegalArgumentException("Value is mandatory.");
this.value = (T)value;
}
Although you will have an unchecked cast.
Hope this helps
I have a large number of Enums that implement this interface:
/**
* Interface for an enumeration, each element of which can be uniquely identified by its code
*/
public interface CodableEnum {
/**
* Get the element with a particular code
* #param code
* #return
*/
public CodableEnum getByCode(String code);
/**
* Get the code that identifies an element of the enum
* #return
*/
public String getCode();
}
A typical example is:
public enum IMType implements CodableEnum {
MSN_MESSENGER("msn_messenger"),
GOOGLE_TALK("google_talk"),
SKYPE("skype"),
YAHOO_MESSENGER("yahoo_messenger");
private final String code;
IMType (String code) {
this.code = code;
}
public String getCode() {
return code;
}
public IMType getByCode(String code) {
for (IMType e : IMType.values()) {
if (e.getCode().equalsIgnoreCase(code)) {
return e;
}
}
}
}
As you can imagine these methods are virtually identical in all implementations of CodableEnum. I would like to eliminate this duplication, but frankly don't know how. I tried using a class such as the following:
public abstract class DefaultCodableEnum implements CodableEnum {
private final String code;
DefaultCodableEnum(String code) {
this.code = code;
}
public String getCode() {
return this.code;
}
public abstract CodableEnum getByCode(String code);
}
But this turns out to be fairly useless because:
An enum cannot extend a class
Elements of an enum (SKYPE, GOOGLE_TALK, etc.) cannot extend a class
I cannot provide a default implementation of getByCode(), because DefaultCodableEnum is not itself an Enum. I tried changing DefaultCodableEnum to extend java.lang.Enum, but this doesn't appear to be allowed.
Any suggestions that do not rely on reflection?
Thanks,
Don
You could factor the duplicated code into a CodeableEnumHelper class:
public class CodeableEnumHelper {
public static CodeableEnum getByCode(String code, CodeableEnum[] values) {
for (CodeableEnum e : values) {
if (e.getCode().equalsIgnoreCase(code)) {
return e;
}
}
return null;
}
}
Each CodeableEnum class would still have to implement a getByCode method, but the actual implementation of the method has at least been centralized to a single place.
public enum IMType implements CodeableEnum {
...
public IMType getByCode(String code) {
return (IMType)CodeableEnumHelper.getByCode(code, this.values());
}
}
Abstract enums are potentially very useful (and currently not allowed). But a proposal and prototype exists if you'd like to lobby someone in Sun to add it:
http://freddy33.blogspot.com/2007/11/abstract-enum-ricky-carlson-way.html
Sun RFE:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570766
To tidy up dave's code:
public class CodeableEnumHelper {
public static <E extends CodeableEnum> E getByCode(
String code, E[] values
) {
for (E e : values) {
if (e.getCode().equalsIgnoreCase(code)) {
return e;
}
}
return null;
}
}
public enum IMType implements CodableEnum {
...
public IMType getByCode(String code) {
return CodeableEnumHelper.getByCode(code, values());
}
}
Or more efficiently:
public class CodeableEnumHelper {
public static <E extends CodeableEnum> Map<String,E> mapByCode(
E[] values
) {
Map<String,E> map = new HashMap<String,E>();
for (E e : values) {
map.put(e.getCode().toLowerCase(Locale.ROOT), value) {
}
return map;
}
}
public enum IMType implements CodableEnum {
...
private static final Map<String,IMType> byCode =
CodeableEnumHelper.mapByCode(values());
public IMType getByCode(String code) {
return byCode.get(code.toLowerCase(Locale.ROOT));
}
}
I had a similar issue with a localization component that I wrote. My component is designed to access localized messages with enum constants that index into a resource bundle, not a hard problem.
I found that I was copying and pasting the same "template" enum code all over the place. My solution to avoid the duplication is a code generator that accepts an XML configuration file with the enum constant names and constructor args. The output is the Java source code with the "duplicated" behaviors.
Now, I maintain the configuration files and the generator, not all of the duplicated code. Everywhere I would have had enum source code, there is now an XML config file. My build scripts detect out-of-date generated files and invoke the code generator to create the enum code.
You can see this component here. The template that I was copying and pasting is factored out into an XSLT stylesheet. The code generator runs the stylesheet transformation. An input file is quite concise compared to the generated enum source code.
HTH,
Greg
Unfortunately, I don't think that there is a way to do this. Your best bet would pro ably be to give up in emums altogether and use conventional class extension and static members. Otherwise, get used to duplicating that code. Sorry.
Create a type-safe utility class which will load enums by code:
The interface comes down to:
public interface CodeableEnum {
String getCode();
}
The utility class is:
import java.lang.reflect.InvocationTargetException;
public class CodeableEnumUtils {
#SuppressWarnings("unchecked")
public static <T extends CodeableEnum> T getByCode(String code, Class<T> enumClass) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
T[] allValues = (T[]) enumClass.getMethod("values", new Class[0]).invoke(null, new Object[0]);
for (T value : allValues) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}
}
A test case demonstrating usage:
import junit.framework.TestCase;
public class CodeableEnumUtilsTest extends TestCase {
public void testWorks() throws Exception {
assertEquals(A.ONE, CodeableEnumUtils.getByCode("one", A.class));
assertEquals(null, CodeableEnumUtils.getByCode("blah", A.class));
}
enum A implements CodeableEnum {
ONE("one"), TWO("two"), THREE("three");
private String code;
private A(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}
}
Now you are only duplicating the getCode() method and the getByCode() method is in one place. It might be nice to wrap all the exceptions in a single RuntimeException too :)
Here I have another solution:
interface EnumTypeIF {
String getValue();
EnumTypeIF fromValue(final String theValue);
EnumTypeIF[] getValues();
class FromValue {
private FromValue() {
}
public static EnumTypeIF valueOf(final String theValue, EnumTypeIF theEnumClass) {
for (EnumTypeIF c : theEnumClass.getValues()) {
if (c.getValue().equals(theValue)) {
return c;
}
}
throw new IllegalArgumentException(theValue);
}
}
The trick is that the inner class can be used to hold "global methods".
Worked pretty fine for me. OK, you have to implement 3 Methods, but those methods,
are just delegators.
It seems like you are actually implementing run time type information. Java provides this as a language feature.
I suggest you look up RTTI or reflection.
I don't think this is possible. However, you could use the enum's valueOf(String name) method if you were going to use the enum value's name as your code.
How about a static generic method? You could reuse it from within your enum's getByCode() methods or simply use it directly. I always user integer ids for my enums, so my getById() method only has do do this: return values()[id]. It's a lot faster and simpler.
If you really want inheritance, don't forget that you can implement the enum pattern yourself, like in the bad old Java 1.4 days.
About as close as I got to what you want was to create a template in IntelliJ that would 'implement' the generic code (using enum's valueOf(String name)). Not perfect but works quite well.
In your specific case, the getCode() / getByCode(String code) methods seems very closed (euphemistically speaking) to the behaviour of the toString() / valueOf(String value) methods provided by all enumeration. Why don't you want to use them?
Another solution would be not to put anything into the enum itself, and just provide a bi-directional map Enum <-> Code for each enum. You could e.g. use ImmutableBiMap from Google Collections for this.
That way there no duplicate code at all.
Example:
public enum MYENUM{
VAL1,VAL2,VAL3;
}
/** Map MYENUM to its ID */
public static final ImmutableBiMap<MYENUM, Integer> MYENUM_TO_ID =
new ImmutableBiMap.Builder<MYENUM, Integer>().
put(MYENUM.VAL1, 1).
put(MYENUM.VAL2, 2).
put(MYENUM.VAL3, 3).
build();
In my opinion, this would be the easiest way, without reflection and without adding any extra wrapper to your enum.
You create an interface that your enum implements:
public interface EnumWithId {
public int getId();
}
Then in a helper class you just create a method like this one:
public <T extends EnumWithId> T getById(Class<T> enumClass, int id) {
T[] values = enumClass.getEnumConstants();
if (values != null) {
for (T enumConst : values) {
if (enumConst.getId() == id) {
return enumConst;
}
}
}
return null;
}
This method could be then used like this:
MyUtil.getInstance().getById(MyEnum.class, myEnumId);