In a Java application I'm working on, I have a number of enums which ended up having a static fromString method in them for converting a string to its actual enum value.
So, I thought I could have a "base" class from which all my enums can extend without have to repeat that code all the time. Since enums cannot extend classes, I've planned to do is that I might be able to do that through an interface instead.
What I've is the following:
public interface IBaseEnum {
String enumVal = null;
public static <T extends Enum<T> & IBaseEnum> Enum<T> fromString(String strVal) {
if (strVal == null) return null;
// T.values() has error because T is not recognised to have the method values()
for (T myEnum : T.values()) {
if (myEnum.enumVal.equals(strVal.toUpperCase())) {
return myEnum;
}
}
return null;
}
}
And then, to inherit that static method, I will implement IBaseEnum in my actual Enum:
public enum Colour implements IBaseEnum {
Red("red");
//...
}
However, I'm having issues with the types in IBaseEnum. The line T.values() is having error because the generic type T cannot be referenced back to the enum itself and so it is complaining that the method values() is not found.
Is this the right way to inherit functionalities in enum? Otherwise, how can I inherit methods in enums so that I don't have to copy/paste and repeat a same set of methods in every single enums?
There are a few reasons why your code would not work, of which I should mention:
String enumVal = null;: IBaseEnum being an interface, numVal gets the implicit public, static, and final modifiers. However, you intend enumVal to be an instance property.
T.values(): of course this doesn't compile. But even if it could (or you had the class instance), you still wouldn't be able to make this dynamic. Static methods are picked at compile time. The only way (that I know) to make it work dynamically would be to use reflection, of course passing in the class object of the enum.
Because you want to be able to call Color.fromString(...), you have no choice but to declare this as a static method in each enum class. With that said, I think the most you can reuse from your logic is the lookup code (again, that's unless you use reflection).
To reuse the lookup logic, you can change the contract of IBaseEnum to make it declare a method that that returns the enumVal value. Beside that, the values() method can be invoked by the enum classes themselves. Here's what it can look like:
interface IBaseEnum {
String enumVal();
public static <T extends Enum<T> & IBaseEnum> T
fromString(String strVal, T[] values) {
if (strVal == null)
return null;
for (T myEnum : values) {
if (myEnum.enumVal().equalsIgnoreCase(strVal)) {
return myEnum;
}
}
return null;
}
}
And that will lead to an enum class like the following:
enum Colour implements IBaseEnum {
VAL1("string")
;
private final String val;
Colour(String v) {
this.val = v;
}
#Override
public String enumVal() {
return this.val;
}
public static Colour fromString(String s) {
return IBaseEnum.fromString(s, values());
}
}
Remember: if enumVal() is intended to return just the enum literal, then you can get rid of all this complexity by just using the valueOf method available in all enums. Only do this if the comparison of your values needs custom logic.
Related
Essentially what I'm trying to do is create a generic method that can take many different kinds of enums. I'm looking for a way to do it how I'm going to describe, or any other way a person might think of.
I've got a base class, and many other classes extend off that. In each of those classes, I want to have an enum called Includes like this:
public enum Includes {
VENDOR ("Vendor"),
OFFERS_CODES ("OffersCodes"),
REMAINING_REDEMPTIONS ("RemainingRedemptions");
private String urlParam;
Includes(String urlParam) {
this.urlParam = urlParam;
}
public String getUrlParam() {
return urlParam;
}
}
I've got a method that takes in a generic class that extends from BaseClass, and I want to be able to also pass any of the includes on that class to the method, and be able to access the methods on the enum, like this:
ApiHelper.Response<Offer> offer = apiHelper.post(new Offer(), Offer.Includes.VENDOR);
public <T extends BaseClass> Response<T> post(T inputObject, Includes... includes) {
ArrayList<String> urlParams = new ArrayList<String>();
for (Include include : includes){
urlParams.add(include.getUrlParam());
}
return null;
}
Is there a way to be able to pass in all the different kinds of enums, or is there a better way to do this?
---EDIT---
I've added an interface to my enum, but how can I generify my method? I've got this:
public <T extends BaseClass> Response<T> post(Offer inputObject, BaseClass.Includes includes) {
for (Enum include : includes){
if (include instanceof Offer.Includes){
((Offer.Includes) include).getUrlParam();
}
}
return null;
}
But I get an error on apiHelper.post(new Offer(), Offer.Includes.VENDOR); saying the second param must be BaseClass.Includes.
Enums can implement interfaces, so you can create an interface with these methods that you'd like to be able to call:
interface SomeBaseClass {
String getUrlParam();
void setUrlParam(String urlParam);
}
and then your enum can implement this interface:
public enum Includes implements SomeBaseClass {
VENDOR ("Vendor"),
OFFERS_CODES ("OffersCodes"),
REMAINING_REDEMPTIONS ("RemainingRedemptions");
private String urlParam;
Includes(String urlParam) {
this.urlParam = urlParam;
}
#Override
public String getUrlParam() {
return urlParam;
}
#Override
public void setUrlParam(String urlParam) {
this.urlParam = urlParam;
}
}
If you want to get really fancy, it's possible to restrict subtypes of the interface to enums, but the generic type declaration will be pretty ugly (thus hard to understand and maintain) and probably won't provide any "real" benefits.
Unrelated note regarding this design: it's a pretty strong code smell that the enum instances are mutable. Reconsider why you need that setUrlParam() method in the first place.
I want to make a refactoring and want to create a generic class for avoiding duplicate code. We have many XXXCriteriaValidator in our project and we want to make one only unique class to substitute them all.
The problem is one line where this class calls for a static method from an Enum. Here you will see. This is more or less what I'mtrying to achieve:
public class GenericCriteriaValidator<T extends ¿SomeKindOfEnumInterface?>
implements CriterionVisitor {
protected Errors errors;
public Errors getErrors() {
return this.errors;
}
/*
* Some code around here
*/
protected void doVisit(final PropertyCriterion criterion) {
if (criterion == null) {
this.errors.reject("error.criterion.null");
} else {
if (criterion.getOperator() == null) {
this.errors.reject("error.operator.null");
}
// Validates property (exception thrown if not exists)
T.fromString(criterion.getName()); // The problem is this call here!!
// Not saying this compiles, just looking
// how to do something equivalent
}
}
}
T is always a differente Enum. The typical enum is like this:
public enum ContactCriteria implements CriteriaInterface<ContactCriteria> {
// ^ This interface is added by me
// for the enum being called in the previous class
CONTACT_ID("this.id"),
CONTACT_COMPANY_ID("this.companyId"),
CONTACT_NAME("this.name"),
CONTACT_EMAIL("this.email"),
CONTACT_PHONE_NUMBER("this.phoneNumber"),
CONTACT_ORDER("this.order"),
private final String alias;
ContactCriteria(final String alias) {
this.alias = alias;
}
public String getAlias() {
return this.alias;
}
public static ContactCriteria fromString(final String name) {
ContactCriteria result = null;
if (name != null) {
result = Enum.valueOf(ContactCriteria.class, name);
}
return result;
}
public ContactCriteria returnThis() {
return this;
}
}
Finally, I'm looking for making an interface for the first class to accept the fromString method of T. I suppose it should be similar to:
public interface CriteriaInterface<T> {
static T fromString(String name);
// ^ This static is important
}
I haven't found none post or strategy for making something similar with an Enum. I know the Enum can implement an interface, but don't know how to get it.
Please help. Thanks in advance
You should start with that a static method is not allowed in Java interface.
The concept behind interfaces strongly disagree with static elements as they belong to class not to object.
So if you have a static method in a enum is just a container that is assigned to but you should not connect it by any other relations.
What is bad here is the design, you try to use enum to something that the are not dedicated on in the way you should not that why you struggle so much.
The question is if a enum instance is an CriteriaInterface then why is should provide it self by name.
Enum contains definition of "constants" that can represent an interface but can not be generic. That why enum can implement interface.
To express that you can define a interface
interface Messanger {
String getMessage();
}
And try to apply it to enum
enum Messages {
INFO
WARNING;
}
You have two options,
First, create a field that will be
enum Messages implements Messanger {
INFO,
WARNING;
private String message;
#Override
public String getMessage() {
return message;
}
}
Then you have to add the constructor to set the field
enum Messages implements Messanger {
INFO("Info"), //We create an instance of class as we call the constructor
WARNING("Warnig") //We create an instance of class as we call the constructor
;
private final String message;
public Message(String message) {
this.messsage = message;
}
#Override
public String getMessage() {
return message;
}
}
As we declare the instances inside the body of the enum you must provide all information required to create it. Assuming that enum would allow generic this is the place where you should declare it.
If the static method is on your CriteriaInterface, shouldn't you do
CriteriaIntervace.fromString("")
since static methods belong to a class (in this case CriteriaIntervace) instead of to an object?
You can't put static methods in an interface, the generics etc have no direct bearing on this. Interfaces define the methods of an instance of an object, static methods are not part of the interface of an instance, they are part of the interface of the class.
The easiest work around will be to provide a factory object to the GenericCriteriaValidator or make it abstract and provide an:
abstract T getEnum(String name);
Each implementation can then implement getEnum for the enum it is using.
Well, generally speaking, the generic type is erased and you have no other chance than explicitly telling the GenericCriteriaValidator what kind of validation logic it should apply. You might want to abstract the receiving of some type away and use a factory pattern for that what would allow you to define an interface for the fromString method.
This would result in something like this:
public interface CriteriaInterface<T> {
static class Factory<U> {
U fromString(String name);
}
}
However, I do not quite see the benefit of that in your example. Simply require an instance of CriteriaInterface<T> as a constructor argument to your GenericCriteriaValidator and define some sort of validate method in this interface.
However, if you really, really want to avoid this, there is a solution. It is possible to read the generic type of the super class of some other class (this is rather hacky, requires reflection and I would not recommend it, but some libraries love this approach). This requires you to always declare an anonymous subclass when using your generic class:
class GenericCriteriaValidator<T extends Enum<?>> implements CriterionVisitor {
private final Method criteria;
public GenericCriteriaValidator() {
ParameterizedType parameterizedType = (ParameterizedType) getClass()
.getGenericSuperclass();
try {
criteria = ((Class<?>) parameterizedType.getActualTypeArguments()[0])
.getMethod("fromString", String.class);
criteria.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException(e);
}
}
#SuppressWarning("unchecked")
private CriteriaInterface<?> invokeFromString(String value) {
try {
return (CriteriaInterface<?>) criteria.invoke(null, value);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
} catch (InvocationTargetException e) {
throw new IllegalArgumentException(e);
}
}
// Your other code goes here.
}
Be aware that you need to instantiate your GenericCriteriaValidator as an anonymous subclass:
new GenericCriteriaValidator<ContactCriteria>() { }; // mind the braces!
As I said. I do not find this intuitive and it is most certainly not the "Java way", but you might still want to consider it.
Given the following interface:
public interface GenericInterface<T> {
T getValue();
void setValue(T newVal);
}
And the following impl:
public class FixedImpl implements GenericInterface<String> {
String value;
public FixedImpl(String value) {
this.value = value;
}
#Override
public String getValue() {
return value;
}
#Override
public void setValue(String newVal) {
value = newVal;
}
}
I want to be able to determine that in the case of FixedImpl, String.class is the value for GenericInterface.T by interrogating FixedImpl.class.
My current idea:
Find a method name in GenericInterface that returns a <T> - in this case, there's "getValue".
Go through all the methods declared in FixedImpl.class with the same name, and collect all the different return types.
The return type farthest from Object is my value for GenericInterface.T.
But there's a couple of issues with this process:
It will only work for generic types containing a method that returns <T>. You can't safely do the same trick using setValue(T), because method overloading by parameter / arity is possible to do in Java source. It only works for T getValue() because overloading by return value isn't (unless I'm mistaken).
It might have weird interactions with Java 8 default methods, or a generic method implementation in a (still generic) possibly abstract superclass.
It's kinda kludgey.
Can anybody point me to an easier / more surefire way to get the same information? I can't seem to find one, but I thought I'd ask the superior intellects of the toobs :)
NB: If you're wondering why I'd need this, it's because I want to programatically construct mocks of container classes with similar hard-coded type parameters, but POJO values rather than simple Strings.
EDIT: I eventually worked out the following solution (before seeing #stony-zhang's):
public static <G> List<Class> getConcreteTypes(Class<? extends G> implClass, Class<G> genericClass) {
List<Class> concreteTypes = new ArrayList<Class>();
for (Type type : implClass.getGenericInterfaces()) {
if (!(type instanceof ParameterizedTypeImpl)) continue;
ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) type;
if (parameterizedType.getRawType() != genericClass) continue;
for (Object arg : parameterizedType.getActualTypeArguments()) {
if (!(arg instanceof Class))
throw new IllegalArgumentException("Class " + implClass + " not concrete for generic type " + genericClass);
concreteTypes.add((Class) arg);
}
}
return concreteTypes;
}
You can get the the class of T by the following way, in the interface add a method getMessageClass(), and in the FixedImpl add the implemented method,
#SuppressWarnings("rawtypes")
public Class getMessageClass() {
int index =0; //In the case, you only have a generic type, so index is 0 to get the first one.
Type genType = getClass().getGenericSuperclass();
if (!(genType instanceof ParameterizedType)) {
return Object.class;
}
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0) {
throw new RuntimeException("Index outof bounds");
}
if (!(params[index] instanceof Class)) {
return Object.class;
}
return (Class) params[index];
}
In you case, if you have multiple subclass, to use it, create one abstract class to implement the interface GenericInterface, and then the all subclass extends from the new abstract class,
public class abstract abstractImpl<T> implements implements GenericInterface<T> {
#SuppressWarnings("rawtypes")
#Override
public Class getMessageClass() {
...............
}
}
Remember type erasure. At runtime, there is no type information about your generics anymore, unless you specify it yourself. And this is what you should do. Add this to your interface:
Class<T> getTypeOfT();
And add this to your FixedImpl:
#Override
public Class<String> getTypeOfT()
{
return String.class;
}
That way, you can always call getTypeOfT() on your GenericInterface<T> implementations and find out what type you are dealing with.
I don't think that you will be able to get reliable result because of Type Erasure:
Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
Insert type casts if necessary to preserve type safety.
Generate bridge methods to preserve polymorphism in extended generic types.
Your approach of of using the types of objects returned may at first seem alright, but beyond the issues you have pointed out there is no way (at runtime) to know if The return type farthest from Object is my value for GenericInterface.T.
My suggestion would be to use some kind of configuration XML which could be generated at build time based on the java source (using a build tool such as Ant), which would in turn be used to create Mock objects, or you could simply generate the tests based off the source at buildtime.
If you don't mind changing your runtime code for the purposes of testing, Jan Doereenhaus' answer suggests a simple hard-coded mechanism for retrieving the type
EDIT:
Consider the scenario:
public class FixedImpl implements GenericInterface<SomeClass> {
#Override
public SomeClass getValue() {
return new SomeClass();
}
}
public class FixedImpl2 extends FixedImpl {
#Override
public SomeClass getValue()
{
return new SomeSubClass();
}
}
From this example, you can see that the sub class of FixedImpl is able to return a subclass of T (which is further down the inheritance hierarchy from Object)
I just found out that Java allows enums to implement an interface. What would be a good use case for that?
Here's one example (a similar/better one is found in Effective Java 2nd Edition):
public interface Operator {
int apply (int a, int b);
}
public enum SimpleOperators implements Operator {
PLUS {
int apply(int a, int b) { return a + b; }
},
MINUS {
int apply(int a, int b) { return a - b; }
};
}
public enum ComplexOperators implements Operator {
// can't think of an example right now :-/
}
Now to get a list of both the Simple + Complex Operators:
List<Operator> operators = new ArrayList<Operator>();
operators.addAll(Arrays.asList(SimpleOperators.values()));
operators.addAll(Arrays.asList(ComplexOperators.values()));
So here you use an interface to simulate extensible enums (which wouldn't be possible without using an interface).
Enums don't just have to represent passive sets (e.g. colours). They can represent more complex objects with functionality, and so you're then likely to want to add further functionality to these - e.g. you may have interfaces such as Printable, Reportable etc. and components that support these.
The Comparable example given by several people here is wrong, since Enum already implements that. You can't even override it.
A better example is having an interface that defines, let's say, a data type. You can have an enum to implement the simple types, and have normal classes to implement complicated types:
interface DataType {
// methods here
}
enum SimpleDataType implements DataType {
INTEGER, STRING;
// implement methods
}
class IdentifierDataType implements DataType {
// implement interface and maybe add more specific methods
}
There is a case I often use. I have a IdUtil class with static methods to work with objects implementing a very simple Identifiable interface:
public interface Identifiable<K> {
K getId();
}
public abstract class IdUtil {
public static <T extends Enum<T> & Identifiable<S>, S> T get(Class<T> type, S id) {
for (T t : type.getEnumConstants()) {
if (Util.equals(t.getId(), id)) {
return t;
}
}
return null;
}
public static <T extends Enum<T> & Identifiable<S>, S extends Comparable<? super S>> List<T> getLower(T en) {
List<T> list = new ArrayList<>();
for (T t : en.getDeclaringClass().getEnumConstants()) {
if (t.getId().compareTo(en.getId()) < 0) {
list.add(t);
}
}
return list;
}
}
If I create an Identifiable enum:
public enum MyEnum implements Identifiable<Integer> {
FIRST(1), SECOND(2);
private int id;
private MyEnum(int id) {
this.id = id;
}
public Integer getId() {
return id;
}
}
Then I can get it by its id this way:
MyEnum e = IdUtil.get(MyEnum.class, 1);
Since Enums can implement interfaces they can be used for strict enforcing of the singleton pattern. Trying to make a standard class a singleton allows...
for the possibility of using reflection techniques to expose private methods as public
for inheriting from your singleton and overriding your singleton's methods with something else
Enums as singletons help to prevent these security issues. This might have been one of the contributing reasons to let Enums act as classes and implement interfaces. Just a guess.
See https://stackoverflow.com/questions/427902/java-enum-singleton and Singleton class in java for more discussion.
It's required for extensibility -- if someone uses an API you've developed, the enums you define are static; they can't be added to or modified. However, if you let it implement an interface, the person using the API can develop their own enum using the same interface. You can then register this enum with an enum manager which conglomerates the enums together with the standard interface.
Edit: #Helper Method has the perfect example of this. Think about having other libraries defining new operators and then telling a manager class that 'hey, this enum exists -- register it'. Otherwise, you'd only be able to define Operators in your own code - there'd be no extensibility.
The post above that mentioned strategies didn't stress enough what a nice lightweight implementation of the strategy pattern using enums gets you:
public enum Strategy {
A {
#Override
void execute() {
System.out.print("Executing strategy A");
}
},
B {
#Override
void execute() {
System.out.print("Executing strategy B");
}
};
abstract void execute();
}
You can have all your strategies in one place without needing a separate compilation unit for each. You get a nice dynamic dispatch with just:
Strategy.valueOf("A").execute();
Makes java read almost like a tasty loosely typed language!
Enums are just classes in disguise, so for the most part, anything you can do with a class you can do with an enum.
I cannot think of a reason that an enum should not be able to implement an interface, at the same time I cannot think of a good reason for them to either.
I would say once you start adding thing like interfaces, or method to an enum you should really consider making it a class instead. Of course I am sure there are valid cases for doing non-traditional enum things, and since the limit would be an artificial one, I am in favour of letting people do what they want there.
Most common usage for this would be to merge the values of two enums into one group and treat them similarly. For example, see how to join Fruits and Vegatables.
For example if you have a Logger enum. Then you should have the logger methods such as debug, info, warning and error in the interface. It makes your code loosely coupled.
One of the best use case for me to use enum's with interface is Predicate filters. It's very elegant way to remedy lack of typness of apache collections (If other libraries mayn't be used).
import java.util.ArrayList;
import java.util.Collection;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
public class Test {
public final static String DEFAULT_COMPONENT = "Default";
enum FilterTest implements Predicate {
Active(false) {
#Override
boolean eval(Test test) {
return test.active;
}
},
DefaultComponent(true) {
#Override
boolean eval(Test test) {
return DEFAULT_COMPONENT.equals(test.component);
}
}
;
private boolean defaultValue;
private FilterTest(boolean defautValue) {
this.defaultValue = defautValue;
}
abstract boolean eval(Test test);
public boolean evaluate(Object o) {
if (o instanceof Test) {
return eval((Test)o);
}
return defaultValue;
}
}
private boolean active = true;
private String component = DEFAULT_COMPONENT;
public static void main(String[] args) {
Collection<Test> tests = new ArrayList<Test>();
tests.add(new Test());
CollectionUtils.filter(tests, FilterTest.Active);
}
}
When creating constants in a jar file, it is often helpful to let users extend enum values. We used enums for PropertyFile keys and got stuck because nobody could add any new ones! Below would have worked much better.
Given:
public interface Color {
String fetchName();
}
and:
public class MarkTest {
public static void main(String[] args) {
MarkTest.showColor(Colors.BLUE);
MarkTest.showColor(MyColors.BROWN);
}
private static void showColor(Color c) {
System.out.println(c.fetchName());
}
}
one could have one enum in the jar:
public enum Colors implements Color {
BLUE, RED, GREEN;
#Override
public String fetchName() {
return this.name();
}
}
and a user could extend it to add his own colors:
public enum MyColors implements Color {
BROWN, GREEN, YELLOW;
#Override
public String fetchName() {
return this.name();
}
}
Another posibility:
public enum ConditionsToBeSatisfied implements Predicate<Number> {
IS_NOT_NULL(Objects::nonNull, "Item is null"),
IS_NOT_AN_INTEGER(item -> item instanceof Integer, "Item is not an integer"),
IS_POSITIVE(item -> item instanceof Integer && (Integer) item > 0, "Item is negative");
private final Predicate<Number> predicate;
private final String notSatisfiedLogMessage;
ConditionsToBeSatisfied(final Predicate<Number> predicate, final String notSatisfiedLogMessage) {
this.predicate = predicate;
this.notSatisfiedLogMessage = notSatisfiedLogMessage;
}
#Override
public boolean test(final Number item) {
final boolean isNotValid = predicate.negate().test(item);
if (isNotValid) {
log.warn("Invalid {}. Cause: {}", item, notSatisfiedLogMessage);
}
return predicate.test(item);
}
}
and using:
Predicate<Number> p = IS_NOT_NULL.and(IS_NOT_AN_INTEGER).and(IS_POSITIVE);
Enums are like Java Classes, they can have Constructors, Methods, etc. The only thing that you can't do with them is new EnumName(). The instances are predefined in your enum declaration.
Here's my reason why ...
I have populated a JavaFX ComboBox with the values of an Enum. I have an interface, Identifiable (specifying one method: identify), that allows me to specify how any object identifies itself to my application for searching purposes. This interface enables me to scan lists of any type of objects (whichever field the object may use for identity) for an identity match.
I'd like to find a match for an identity value in my ComboBox list. In order to use this capability on my ComboBox containing the Enum values, I must be able to implement the Identifiable interface in my Enum (which, as it happens, is trivial to implement in the case of an Enum).
I used an inner enum in an interface describing a strategy to keep instance control (each strategy is a Singleton) from there.
public interface VectorizeStrategy {
/**
* Keep instance control from here.
*
* Concrete classes constructors should be package private.
*/
enum ConcreteStrategy implements VectorizeStrategy {
DEFAULT (new VectorizeImpl());
private final VectorizeStrategy INSTANCE;
ConcreteStrategy(VectorizeStrategy concreteStrategy) {
INSTANCE = concreteStrategy;
}
#Override
public VectorImageGridIntersections processImage(MarvinImage img) {
return INSTANCE.processImage(img);
}
}
/**
* Should perform edge Detection in order to have lines, that can be vectorized.
*
* #param img An Image suitable for edge detection.
*
* #return the VectorImageGridIntersections representing img's vectors
* intersections with the grids.
*/
VectorImageGridIntersections processImage(MarvinImage img);
}
The fact that the enum implements the strategy is convenient to allow the enum class to act as proxy for its enclosed Instance. which also implements the interface.
it's a sort of strategyEnumProxy :P the clent code looks like this:
VectorizeStrategy.ConcreteStrategy.DEFAULT.processImage(img);
If it didn't implement the interface it'd had been:
VectorizeStrategy.ConcreteStrategy.DEFAULT.getInstance().processImage(img);
I could be wrong but I'm guessing from Why can't enums be declared locally in a method?
that, since an enum in Java cannot be declared locally, that therefore it is problematic for a method to return type Enum? I can declare that a method should return an Enum (see below) but how would one then go about implementing such a method to return anything other than null, or a reference to an Enum declared outside the method? My first inclination would be to investigate using Generics for this but I'd like to avoid any deadends if the SO community can help me avoid them.
private Enum resources() {
return null;
}
I think you're correct, it's only going to be able to either return null or an Enum declared somewhere else. But you don't necessarily have to specify that "something else" at compile time.
class EnumEnumerator<T extends Enum<T>> implements Iterable<T> {
private final Class<T> enumClass;
public EnumEnumerator(Class<T> enumClass) {
this.enumClass = enumClass;
}
public Iterator<T> iterator() {
T[] values = enumClass.getEnumConstants();
return Arrays.asList(values).iterator();
}
}
Later, you invoke it by specializing the generic constructor and passing in the enum class you're interested in:
class EnumEnumeratorDemo {
enum Foo {
BAR, BAZ, QUX;
#Override public String toString() {
return name().toLowerCase();
}
}
public static void main(String[] args) {
for (Foo f : new EnumEnumerator<Foo>(Foo.class)) {
System.out.println(f);
}
}
}
(Obviously this is a contrived example and in real life you should just call Foo.values(), but you get the idea.)
The entire point of the way Java does Enums is that they are typesafe--so you wouldn't return an Enum (that would be double-plus ungood) instead you return the actual type you define (like "Suit") which acts just like a class. Suit has 4 "Enumerated" instances.
If you were expecting a "Suit", what good would it be to return a "Rank" of 7? It would break everything!
Also if you passed an "Enum" or some generic value, you couldn't call methods on it. The coolest thing about TypeSafe Enums is that you can just get a "Suit" and call "Suit.getColor()" and fully expect to get the color of that suit. You could also have a ranksHigherThan(Suit s) which might fulfill:
assertTrue(SPADES.ranksHigherThan(HEARTS));
Or, more importantly:
suit1.ranksHigherThan(suit2);
(assuming they were both passed in and you don't know what they are)
Type safety is really amazing (even though it feels a little uncomfortable at first), embrace it.
All enums implement the interface Enum, so you can certainly write a method that returns an enum this way. But this method will return a single enum value. There is no way to return a generic value which encompasses the whole enum (apart from returning the class and doing reflection). You can however return all the enum values which is more or less what you want I think.
enum Resources { ONE, TWO, THREE }
private Enum<?>[] resources() {
return Resources.values();
}
One benefit of this approach is you can return more or less values for example:
enum Resources { ONE, TWO, THREE }
enum MoreResources { UN, DEUX, TROIS }
private Enum<?>[] resources() {
List<Enum<?>> resources = new ArrayList<Enum<?>>();
resources.addAll(Arrays.asList(Resources.values());
resources.addAll(Arrays.asList(MoreResources.values());
return resources.toList(new Enum<?>[] {});
}
An even better approach that is more typesafe is to have the enums of interest
implement a common interface e.g.
public interface Resources {}
enum SomeResources implements Resources { ONE, TWO, THREE }
enum MoreResources implements Resources { UN, DEUX, TROIS }
private Resources[] resources() {
List<Resources> resources = new ArrayList<Resources>();
resources.addAll(Arrays.asList(Resources.values());
resources.addAll(Arrays.asList(MoreResources.values());
return resources.toList(new Resources[] {});
}
You can add additional methods to the interface to provide more functionality.
What are you trying to accomplish? This is a way to return an Enum:
public class Test
{
public static void main(String args[])
{
System.out.println(doit());
}
public enum Foo {
BAR,
BAZ;
}
public static Enum doit() {
return Enum.valueOf(Foo.class,"BAR");
}
}
But, I'm guessing this is not what you are going for?
Yes, it definitely is possible.
private Enum getRetentionPolicy() {
return java.lang.annotation.RetentionPolicy.SOURCE;
}
If your question is about declaring Enums, you may declare them:
in their own java file, similar to a top-level class;
within a java file belonging to another class, similar to a static inner class;
Not totally sure what your goal is, but if you wanted to return a generified method (i.e. one that would be overridden) you might have something like the following:
public class MyEnumClass<T extends Enum<T>> {
public T resources() {
//do stuff here
}
}
Not entirely sure what you would gain there, although it can be beneficial if you are talking about different sets of Enums and their elements.
If you are talking about the Enum class (i.e. the percursor to Iterator) as far as I know it has not been generified, so I am not sure generics would help much here.
You can refer to a value of an enum by its name, e.g. Suit.SPADES.
You can iterate over all values by using the values() method and pick one of the values.