Declare enum without specify values, something like abstract - java

I have an abstract class (or an interface). In this class I want to define an enum, in order to force classes that extend this abstract class (or implement this interface) to declare an enum with the same name.
abstract class Operator {
public abstract enum Symbol;
public Symbol value;
}
class Binary extends Operator {
public enum Symbol {
pls,
min,
mul,
div,
//...
}
}
class Unary extends Operator {
public enum Symbol {
sin,
cos,
tan,
cot,
//...
}
}
Assume I can't know the values of sub classes enums. I want that every extending class had an enum with that name and its values. I want to use enums (especially because it's easy to switch enums)

There's no way to do this thing and moreover, even if it were, how would you call the subclass' implementation? I mean, only method calls can be virtual, ie dispatched at runtime. Types can not, so without cheating with reflection (which throws away any type safety anyhow, so that you don't even need to subclass), you would not be able to call the overridden type (in fact, types can't be overridden).
Maybe you can still achive your objectives by using composition:
public abstract class Operator<T extends Enum<T>> {
public final Class<T> symbol;
public Operator(Class<T> symbol) { this.symbol = symbol; }
}
public enum BinarySymbol { PLS, MIN, MUL, DIV }
public class Binary extends Operator<BinarySymbol> {
public Binary(Object operand1, Object operand2, BinarySymbol symbol) {
super(symbol);
}
}
Your base class Operator can dynamically read the enumerated values through reflection, via Class.getEnumConstants()

You can't enforce it at compile time. One way would be to use reflection at runtime to see if the class has been implemented correctly. I don't suggest this, but it's possible.

What you can do is have enums that implement a common interface, and then utilize those interfaces:
public interface YourEnumInterface<E extends Enum<E> & YourEnumInterface<E>> {
//methods that your enum should be implementing
}
The extension for the interface generic declaration is there to guarantee it is only called by enums that implement your interface
And then any enum you have to specify can implement it like so:
public enum MyEnum implements YourEnumInterface<MyEnum> {
// enum constants
TEST_VALUE;
// implementation of interface methods
}
From there, you would simply work with the YourEnumInterface as an object, and you can pass enum values for them:
public void doSomething(YourEnumInterface enm) {
//work with enm
}
//Elsewheres...
doSomething(MyEnum.TEST_VALUE);
It should be noted, that once you lower your enum down to the interface itself, you won't be able to change the constant you are working with (without casting, which can potentially be unsafe). This should really be used more or less for passing things to a destination that just works with the values (like a config enum, or internalization of strings, etc)
So in relevance to forcing a subclass to implement it:
public class YourSuperClass {
public abstract YourEnumInterface symbol;
}
A runnable example
public class EnumMagic {
public static void main(String[] args) {
YourSubClass clazz = new YourSubClass();
//prints the default value
System.out.println(clazz.getEnum().getValue());
//gets the value of a specified enum constant
System.out.println(clazz.getEnum().SECOND_TEST.getValue());
}
}
abstract class YourSuperClass {
protected YourEnumInterface symbol;
public abstract YourEnumInterface getEnum();
}
interface YourEnumInterface<E extends Enum<E> & YourEnumInterface<E>> {
public int getValue();
}
class YourSubClass extends YourSuperClass {
public enum MyEnum implements YourEnumInterface<MyEnum> {
TEST_VALUE(1),
SECOND_TEST(2);
private final int val;
private MyEnum(int example) {
this.val = example;
}
public int getValue() {
return this.val;
}
}
public YourSubClass() {
this.symbol = MyEnum.TEST_VALUE;
}
public MyEnum getEnum() {
return MyEnum.TEST_VALUE;
}
}
The output of this progam is:
1
2
And you can simply get the class' specified enum constant via getEnum, which they will return their own internal enum.
However, once downcasted to the super type, e.g. YourSuperClass intc = clazz;, then you will lose this ability to specify the enum itself. Depending on how you store your instances will determine whether or not this requires changes.

Related

Java Method that returns different types of generic Lists

I'm currently trying to write a method that goes through a list of Ant-Objects and returns a list of AntScouts, that extend Ant. In general, List<Ant> can contain a lot of different Objects that inherit from Ant.
I also have an enum for the different kinds of ants:
public enum AntType {
QUEEN,WARRIOR,GATHERER,SCOUT;
public Class getClass(AntType type){
return switch (type) {
case QUEEN -> AntQueen.class;
case WARRIOR -> AntWarrior.class;
case GATHERER -> AntGatherer.class;
case SCOUT -> AntScout.class;
};
}
}
This enum causes a warning:
Raw use of parameterized class 'Class'
And this is the method that currently returns a List<Ant>.
public List<Ant> getAntsType(AntType type){
return ants.stream().filter(ant -> ant.getType() == type).toList();
}
How can I write the method so that it get's the AntType enum as argument and returns a List<AntScout> or List<AntWarrior> corresponding to the enum? I REALLY don't want to use Class<T> clazz as argument since that would defeat the point of the enum. (I also use that enum elsewhere, so I can't get rid of it)
How can I write the method so that it get's the AntType enum as argument and returns a List or List corresponding to the enum?
Edit: This comment probably comes closest to the desired solution:
Java Method that returns different types of generic Lists
Use the Power of Polymorphism
How can I write the method so that it get's the AntType enum as argument and returns a List or List corresponding to the enum?
You're overengineering your code for no good reason.
When you're using inheritance, your classes should be designed in a way that allow to benefit from the Polymorphism.
I.e. by using super type Ant for all your objects and interacting with them through overridden behavior without a need to discriminate between the concrete implementations and operating via type casts.
Therefore, your method returning List<Ant> is quite fine.
And even if you wanted to obtain a List<AntQueen> or List<AntScout> as a result of the method execution then you would need a to use a generic type variable T, or rather T extends Ant, and that would imply that you need a mean of representing the T. And enum would not help you with this task because in Java enums can't be generic. You need to provide as a method argument either an instance of T or a Class<T>.
public <T extends Ant> List<T> getAntsByType(Class<T> tClass) {
return ants.stream().filter(tClass::isAssignableFrom).toList();
}
But I would advise sticking with the initial version returning a List of super type Ant declaring method getType() which returns an instance of enum AntType.
public List<Ant> getAntsByType(AntType type) {
return ants.stream().filter(ant -> ant.getType() == type).toList();
}
And as I've said, Java-enums can't be generic, there's no way to obtain Class<T> through it. Hence, you can remove contrived method getClass() from AntType.
public enum AntType {
QUEEN, WARRIOR, GATHERER, SCOUT;
}
Simulated self-type
But if you're still convinced that your application logic require the ability to generate a list of concrete type like List<AntScout> from a list of super type, then you can make use of a recursive type bound.
For that, you need to define the super type as Ant<T extends Ant<T>>.
This approach is also called a simulated self-type idiom and can be observed in the declaration of the parent type of all enums java.lang.Enum<E extends Enum<E>> and in some other parts of the JDK like method Collections.sort(List<T>) where T is defined as <T extends Comparable<? super T>>.
Let's apply self-type idiom for this case.
Consider super type Ant defined as an interface, declaring a self-returning method (you can change into abstract class if you need to declare some skeletal implementations and common fields):
interface Ant<T extends Ant<T>> {
T self();
AntType getType();
}
And here's a couple of concrete classes:
public static class AntWarrior implements Ant<AntWarrior> {
#Override
public AntWarrior self() {
return this;
}
#Override
public AntType getType() {
return AntType.WARRIOR;
}
}
public static class AntScout implements Ant<AntScout> {
#Override
public AntScout self() {
return this;
}
#Override
public AntType getType() {
return AntType.SCOUT;
}
}
That how we can perform conversion using self() method:
#SuppressWarnings("unchecked")
public static <T extends Ant<T>> List<T> getAntsByType(List<Ant<?>> ants,
AntType type) {
return ants.stream()
.filter(ant -> ant.getType() == type)
.map(ant -> (T) ant.self())
.toList();
}
Usage example:
public static void main(String[] args) {
List<Ant<?>> ants = List.of(new AntWarrior(), new AntScout());
// compiles and runs without issues
List<AntWarrior> antWarriors = getAntsByType(ants, AntType.WARRIOR);
System.out.println(antWarriors);
// compiles and runs without issues
List<AntScout> antScouts = getAntsByType(ants, AntType.SCOUT);
System.out.println(antScouts);
}
Output:
[AntWarrior{}]
[AntScout{}]
A link to Online Demo
This could be possible if enums could be generic, but they can't. However, that is no big deal. Just use a final class with a bunch of public static final fields and a private constructor. A little verbose surely, but is as effective as an enum.
Also, your getClass() method should either be a static method with the switch or else be an instance method without the switch. The later is much better, so went that way. Further, calling it getClass() is not a good idea since it is unrelated with Object.getClass() method. So I called it getAntTypeClass().
And this is the result:
public class Main {
public static void main(String[] args) {
System.out.println(AntType.QUEEN.getAntTypeClass().getName());
System.out.println(AntType.SCOUT.getAntTypeClass().getName());
}
}
final class AntType<T extends Ant> {
public static final AntType<AntQueen> QUEEN = new AntType<>(AntQueen.class );
public static final AntType<AntWarrior> WARRIOR = new AntType<>(AntWarrior.class );
public static final AntType<AntGatherer> GATHERER = new AntType<>(AntGatherer.class);
public static final AntType<AntScout> SCOUT = new AntType<>(AntScout.class );
private final Class<T> antTypeClass;
private AntType(Class<T> antTypeClass) {
this.antTypeClass = antTypeClass;
}
public Class<T> getAntTypeClass() {
return antTypeClass;
}
}
interface Ant {}
class AntWarrior implements Ant {}
class AntGatherer implements Ant {}
class AntScout implements Ant {}
class AntQueen implements Ant {}
See it working on ideone.
I would change your AntType enum method so that it acts as the filter in your stream. I've had to guess at the rest of the class hierarchy but this might give you a starting point.
import java.util.List;
import static java.util.stream.Collectors.toList;
public class Demo {
private List<Ant> ants = List.of(
new AntQueen(),
new AntScout(),
new AntGatherer(),
new AntWarrior());
public static void main(String[] args) {
var demo = new Demo();
System.out.println(demo.getAntsType(AntType.QUEEN));
}
public List<Ant> getAntsType(AntType type) {
return ants.stream().filter(type::matches).collect(toList());
}
}
class Ant {}
class AntQueen extends Ant {}
class AntWarrior extends Ant {}
class AntGatherer extends Ant {}
class AntScout extends Ant {}
enum AntType {
QUEEN, WARRIOR, GATHERER, SCOUT;
public boolean matches(Ant a) {
return switch (this) {
case QUEEN -> a instanceof AntQueen;
case WARRIOR -> a instanceof AntWarrior;
case GATHERER -> a instanceof AntGatherer;
case SCOUT -> a instanceof AntScout;
};
}
}
There are a couple ways you can do this.
First, fix the method in your enum:
public enum AntType {
QUEEN,WARRIOR,GATHERER,SCOUT;
public Class<? extends Ant> getImplClass(){
return switch (this) {
case QUEEN -> AntQueen.class;
case WARRIOR -> AntWarrior.class;
case GATHERER -> AntGatherer.class;
case SCOUT -> AntScout.class;
};
}
}
Since this is a non static method, you don't need to take in the type as an argument. In your example it's not clear where the list is coming from, but if I add it as an argument, it would look like this:
public static List<Ant> getAntsType(AntType type, List<Ant> ants){
return ants.stream().filter(ant -> ant.getClass() == type.getImplClass()).toList();
}
The second way to do it would be to add a method called getType() in the Ant class which returns a type variable that is set by the constructor.
public class Ant {
private AntType type;
protected Ant(AntType type) {
this.type = type;
}
public AntType getType() {
return type;
}
}
Then you set the type in each of the subclass's constructors:
public class AntQueen extends Ant {
protected AntQueen() {
super(AntType.QUEEN);
}
}
Then the filtering code looks like this:
public static List<Ant> getAntsType(AntType type, List<Ant> ants){
return ants.stream().filter(ant -> ant.getType() == type).toList();
}

java generics: Bound mismatch for string

my code is as below, and I got the error message Bound Mismatch Error: The type String is not a valid substitute for the bounded parameter <K extends myComparable<K>> of the type myInterface<K,V>:
interface myComparable<T> {
public int compareTo(T o);
}
interface myInterface<K extends myComparable<K>, V> {
}
public class myClass implements myInterface<String,String>{
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
However, if I changed K extends myComparable<K> to K extends Comparable<K> (without changing the first line; i.e. to use Comparable instead of myComparable), the error will be solved.
Why? And how can I use my own myComparable?
I finally got a solution (i.e. to use myString instead of String):
interface myComparable<T> {
public int compareTo(T o);
}
interface myInterface<K extends myComparable<K>, V> {
}
class myString implements myComparable<myString>{
#Override
public int compareTo(myString o) {
return 0;
}
}
public class myClass implements myInterface<myString,myString>{
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
When you write implements myInterface<String, String>, you're 'binding' the K type variable to String and the V type variable to String.
The declaration of the K type variable in particular has a bound on it: You've declared it as myInterface<K extends myComparable<K>, V> which means that any bound you pick for K must at least 'fit' this restriction.
And it doesn't, which is why the compiler won't let you.
The java.lang.String class actually implements Comparable<String> - it's right there in the javadoc as well as the source if you care to look; you can also just cast it:
Comparable<String> test = "hello"; // this compiles and runs fine.
The reason is that string was written by sun/oracle as: public final class String implements Comparable<String>.
It was not written with implements myComparable<String>.
It is not possible to make java.lang.String implement your interface.
That is not how interfaces work; java is nominally and not structurally typed: You can't decree that all Strings are myComparables, just because they so happen to have a compareTo method.
Imagine it worked that way and I wrote this class:
public class Gun {
public void shoot(Person person) { ... }
}
quite a dangerous class!
Let's say it worked the way you appear things are. Then I could do:
public interface Camera {
public void shoot(Person p);
}
Camera c = new Gun();
c.shoot(somebody);
and good grief, now we have an extremely dangerous situation going on. Fortunately, java does not work this way; A Gun is not a Camera. Eventhough it so happens to have all the methods that the Camera interface declared.
You can make your own types that implement your own interfaces, of course. That's no problem. However, in general, it doesn't seem useful to make an interface named myComparable.

How to find all sub classes of implemented interface in java?

How to get Subclass object using implemented interface, if interface is used as Type Parameter for DynamoDBTypeConverter.(e.g. DynamoDBTypeConverter ).
public enum state implements EnumInterface{
CREATED("0");
}
public enum color implements EnumInterface{
GREEN("0");
}
public interface EnumInterface{
void getStatus();
}
public class DynamoDbEnumConverter implements DynamoDBTypeConvereter<String,EnumInterface>{
public EnumInterface unconvert(String value){
// find Object run time, EnumInterface represent color or stat
}
}
Get whether Enum interface represents color or state in unconvert method.
Check this page out: What are Reified Generics? How do they solve Type Erasure problems and why can't they be added without major changes?
Generics are erased in Java.
The only way you're going to get your code to work without hacking around is by providing one instance of the DynamoDbEnumConverter for each EnumInterface:
class DynamoDbEnumConverter<T extends Enum<T> & EnumInterface> implements DynamoDBTypeConvereter<String, T> {
private Class<T> enumType;
public DynamoDbEnumConverter(Class<T> enumType) {
this.enumType = enumType;
}
public EnumInterface unconvert(String value) {
return Enum.valueOf(enumType, value);
}
}
And then:
DynamoDbEnumConverter<Color> colorConverter = new DynamoDbEnumConverter<>(Color.class);

Generic type meaning for java.lang.Enum [duplicate]

I thought I understood Java generics pretty well, but then I came across the following in java.lang.Enum:
class Enum<E extends Enum<E>>
Could someone explain how to interpret this type parameter? Bonus points for providing other examples of where a similar type parameter could be used.
It means that the type argument for enum has to derive from an enum which itself has the same type argument. How can this happen? By making the type argument the new type itself. So if I've got an enum called StatusCode, it would be equivalent to:
public class StatusCode extends Enum<StatusCode>
Now if you check the constraints, we've got Enum<StatusCode> - so E=StatusCode. Let's check: does E extend Enum<StatusCode>? Yes! We're okay.
You may well be asking yourself what the point of this is :) Well, it means that the API for Enum can refer to itself - for instance, being able to say that Enum<E> implements Comparable<E>. The base class is able to do the comparisons (in the case of enums) but it can make sure that it only compares the right kind of enums with each other. (EDIT: Well, nearly - see the edit at the bottom.)
I've used something similar in my C# port of ProtocolBuffers. There are "messages" (immutable) and "builders" (mutable, used to build a message) - and they come as pairs of types. The interfaces involved are:
public interface IBuilder<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
public interface IMessage<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
This means that from a message you can get an appropriate builder (e.g. to take a copy of a message and change some bits) and from a builder you can get an appropriate message when you've finished building it. It's a good job users of the API don't need to actually care about this though - it's horrendously complicated, and took several iterations to get to where it is.
EDIT: Note that this doesn't stop you from creating odd types which use a type argument which itself is okay, but which isn't the same type. The purpose is to give benefits in the right case rather than protect you from the wrong case.
So if Enum weren't handled "specially" in Java anyway, you could (as noted in comments) create the following types:
public class First extends Enum<First> {}
public class Second extends Enum<First> {}
Second would implement Comparable<First> rather than Comparable<Second>... but First itself would be fine.
The following is a modified version of the explanation from the book Java Generics and Collections:
We have an Enum declared
enum Season { WINTER, SPRING, SUMMER, FALL }
which will be expanded to a class
final class Season extends ...
where ... is to be the somehow-parameterised base class for Enums. Let's work
out what that has to be. Well, one of the requirements for Season is that it should implement Comparable<Season>. So we're going to need
Season extends ... implements Comparable<Season>
What could you use for ... that would allow this to work? Given that it has to be a parameterisation of Enum, the only choice is Enum<Season>, so that you can have:
Season extends Enum<Season>
Enum<Season> implements Comparable<Season>
So Enum is parameterised on types like Season. Abstract from Season and
you get that the parameter of Enum is any type that satisfies
E extends Enum<E>
Maurice Naftalin (co-author, Java Generics and Collections)
This can be illustrated by a simple example and a technique which can be used to implement chained method calls for sub-classes. In an example below setName returns a Node so chaining won't work for the City:
class Node {
String name;
Node setName(String name) {
this.name = name;
return this;
}
}
class City extends Node {
int square;
City setSquare(int square) {
this.square = square;
return this;
}
}
public static void main(String[] args) {
City city = new City()
.setName("LA")
.setSquare(100); // won't compile, setName() returns Node
}
So we could reference a sub-class in a generic declaration, so that the City now returns the correct type:
abstract class Node<SELF extends Node<SELF>>{
String name;
SELF setName(String name) {
this.name = name;
return self();
}
protected abstract SELF self();
}
class City extends Node<City> {
int square;
City setSquare(int square) {
this.square = square;
return self();
}
#Override
protected City self() {
return this;
}
public static void main(String[] args) {
City city = new City()
.setName("LA")
.setSquare(100); // ok!
}
}
You are not the only one wondering what that means; see Chaotic Java blog.
“If a class extends this class, it should pass a parameter E. The parameter E’s bounds are for a class which extends this class with the same parameter E”.
This post has totally clarified to me these problem of 'recursive generic types'.
I just wanted to add another case where this particular structure is necessary.
Suppose you have generic nodes in a generic graph:
public abstract class Node<T extends Node<T>>
{
public void addNeighbor(T);
public void addNeighbors(Collection<? extends T> nodes);
public Collection<T> getNeighbor();
}
Then you can have graphs of specialized types:
public class City extends Node<City>
{
public void addNeighbor(City){...}
public void addNeighbors(Collection<? extends City> nodes){...}
public Collection<City> getNeighbor(){...}
}
If you look at the Enum source code, it has the following:
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
public final int compareTo(E o) {
Enum<?> other = (Enum<?>)o;
Enum<E> self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;
}
#SuppressWarnings("unchecked")
public final Class<E> getDeclaringClass() {
Class<?> clazz = getClass();
Class<?> zuper = clazz.getSuperclass();
return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
}
public static <T extends Enum<T>> T valueOf(Class<T> enumType,
String name) {
T result = enumType.enumConstantDirectory().get(name);
if (result != null)
return result;
if (name == null)
throw new NullPointerException("Name is null");
throw new IllegalArgumentException(
"No enum constant " + enumType.getCanonicalName() + "." + name);
}
}
First thing first, what does E extends Enum<E> mean? It means the type parameter is something that extends from Enum, and isn't parametrized with a raw type (it's parametrized by itself).
This is relevant if you have an enum
public enum MyEnum {
THING1,
THING2;
}
which, if I know correctly, is translated to
public final class MyEnum extends Enum<MyEnum> {
public static final MyEnum THING1 = new MyEnum();
public static final MyEnum THING2 = new MyEnum();
}
So this means that MyEnum receives the following methods:
public final int compareTo(MyEnum o) {
Enum<?> other = (Enum<?>)o;
Enum<MyEnum> self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;
}
And even more importantly,
#SuppressWarnings("unchecked")
public final Class<MyEnum> getDeclaringClass() {
Class<?> clazz = getClass();
Class<?> zuper = clazz.getSuperclass();
return (zuper == Enum.class) ? (Class<MyEnum>)clazz : (Class<MyEnum>)zuper;
}
This makes getDeclaringClass() cast to the proper Class<T> object.
A way clearer example is the one that I answered on this question where you cannot avoid this construct if you want to specify a generic bound.
According to wikipedia, this pattern is called Curiously recurring template pattern.
Basically, by using the CRTP pattern, we can easily refer to subclass type without type casting, which means by using the pattern, we can imitate virtual function.

How can I define a template class by constraining the set of allowed types, and reference a Collection of these in Java?

I am defining the following class:
public class Foo<T> {
T _value;
public T getValue() {
return T;
public void setValue(T value) {
_value = value;
}
}
T should only be of type int, char, or double.
I want to be able to reference a collection of these, such as:
interface IBar {
Collection<Foo> getAllFoo();
}
Obviously, this doesn't work since I'd need to specify the type T with this reference. So, I need to define some abstract base class that I can use instead.
The question is, how can I enforce that all derived types implement the getValue() and setValue() functions? I know I can define them in the abstract base as abstract methods returning / accepting an Object, but that doesn't provide type safety on the 3 accepted primitives.
Is there a better way to define a collection of these, and is there a way to enforce T being either int, char, or double?
You're better off creating concrete implementations for each type you care about.
interface Foo<T>{
public T getValue();
public void setValue(T value);
}
class IntFoo implements Foo<Integer>{...}
class CharFoo implements Foo<Character>{...}
class DoubleFoo implements Foo<Double>{...}
interface Bar{
Collection<Foo<?>> getAllFoo();
}
The ? allows the collection to contain any type of Foo object. You still lose the generic type when you reference a Foo<?>, but there's no good way around that.
Other than having the common base class, there really is no advantage of doing this. If you had some common ground each Foo could resolve to, then I would do this:
abstract class Foo<T>{
T value;
T getValue(){
return value;
}
void setValue(T value){
this.value=value;
}
// return whatever is appropriate for all implementations
abstract Object baz();
}
class IntFoo implements Foo<Integer>{
Object baz(){
return null // something useful;
}
}
Collection<Foo<?>> foos = bar.getAllFoo();
for(Foo<?> foo:foos){
foo.baz();
}
public class Foo<T>
private Foo(){} // only nested classes can access
static public class Int extends Foo<Integer>{}
static public class Char extends Foo<Character>{}
static public class Double extends Foo<Double>{}
public class MyIntFoo extends Foo.Int // MyIntFoo is a Foo<Integer>
There is no way to create a subclass of Foo whose T is not one of Integer/Character/Double. If the 3 nested classes are final, then they are the only subclasses of Foo.
We still can't prevent a Foo<Float> type declaration. But at least you know such an object cannot be instantiated.

Categories