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);
Related
I have a class that is paramaterised with an extend of Enum.
public class MyClass<EnumType extends Enum> {
public MyClass(){
Enum<?>[] enums = EnumType.getEnumConstants();
}
}
The line:
Enum<?>[] enums = EnumType.getEnumConstants()
fails to compile with "can not resolve method".
How can I get to the base type and get the enums?
OTOH, if I do the following it works ok:
public void setEnumType(Class <? extends Enum> clazz){
Enum<?>[] enums = clazz.getEnumConstants();
}
I can't pass this into the constructor as it is a custom view which is directly inserted in the parent.
Owing to erasure, you have to pass an instance of the enum class to the constructor:
public class MyClass<EnumType extends Enum<EnumType>> {
// ^ don't forget this
public MyClass(Class<EnumType> c){
Enum<?>[] enums = c.getEnumConstants();
}
}
MyClass<YourEnum> m = new MyClass<>(YourEnum.class);
Or, you could pass YourEnum.values() directly. The risk there is that a caller can pass any array, not necessarily one with all values, without duplicates, in the right order etc.
I'm a java newbie, and I have some codes like below.
public interface TestJava<T extends MyClass, U> {
public U func(T t);
}
The problem is that U is totally dependant on T so that if T is determined, U is also determined (declaring U is unnecessary!). As an example, if T is String, then U must be Integer and cannot be others. In C++, U can be easily removed using the keyword typedef like below if T is a user-defined class.
class UserDefinedClass {
public:
typedef int ReturnType;
};
template<class T> class TestCpp {
T::ReturnType func(T t);
};
However, java doen't have such keyword (as far as I know), so I have no idea how to achieve this.
Note that T in the java code is a user-defined object, not String, Integer or others.
Don't get confused with the example :)
One thing you could do is hide the eyesore by extending the interface and then from then on just call the extended interface. The point here is that you don't have to pass in the second type if you are SURE it will always be (eg: Integer*) the same.
public class MyClass{
boolean truth;
}
public interface Lame{
}
public interface TestJava<T extends MyClass, U> {
public U func(T t);
}
public interface TestJavaMore<T extends MyClass> extends Lame{
public void funky();
}
public interface TestJavaEvenMore<T extends MyClass> extends TestJava<T, Integer> {
}
Another solution which I think I would recommend if you have more than one combination of types for T and U is to use a factory to create a concrete instance with the types you want. This is a common pattern you can research, but in this case, it's something like:
public class TestJavaImpl<T extends MyClass, U> implements TestJava{
#Override
public Object func(MyClass t) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
public TestJava TestJavaFactory(){
TestJava testJava = null;
if (true == true){
testJava = new TestJavaImpl<MyClass, Integer>();
} else {
testJava = new TestJavaImpl<MyClass, Float>();
}
return testJava;
}
*Tip:Remember too w/ java and templates you have to use "I"nteger not "i"nteger
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.
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.
I would like to declare attribute that holds instance of class that implements 2 different interfaces. I have tried this syntax:
private <? extends Interface1 & Interface2> name;
and this:
private <T extends Interface1 & Interface2> T name;
None of those work. Is it possible? What's the syntax? I'm trying to avoid declaring another interface that inherits from both Interface1 and Interface2.
Edit:
The class containing this attribute should not have any type arguments. That is nothing like this:
public class MyClass<T extends Interface1 & Interface2>{
private T name;
...
}
It would not make any sense for those using the class. It is not expected neither logical not possible for that class to be generic.
That needs to go in the class declaration, such as:
public class TestG<T extends Cloneable & Serializable> {
private T name;
}
One alternative is to set it in a method (but not a variable)
public class TestG {
public <T extends Cloneable & Serializable> void method(T parameter) {
}
}
A variable cannot be generic.
private <T> T var;
is not possible - at which point is T defined? When accessing var, I cannot make much assumptions on what I used at assignment time.
Java allows generics on classes and on methods. So you can have
private <T implements Cloneable & Serializable> void setVar(T val);
and you can have a class-wide type T.
But always remember that in the end, it is implemented by type erasure. You can always emulate more complex logic using getters, setters and casts. When done properly, it will give you just as much type safety.
The simplest way to obtain a variable with the type safety you want is to just use two variables, and a setter to keep them in sync.
private Serializable vars;
private Cloneable vars;
will of course give you a good type safety. But yes, it needs 4 bytes of additional memory, and a setter.
Here's the casting approach you asked:
private Object internal_var;
// Implementation notice: do not remove this generic.
// Due to a Java limitation, we *do* want these two constraints!
public <T extends Serializable & Cloneable> void setVar(T val) {
internal_var = val;
}
public Serializable getSerializable() {
return (Serializable) internal_var; // Type checked in setter!
}
public Cloneable getCloneable() {
return (Cloneable) internal_var; // Type checked in setter!
}
// This is the way to use it in a generic getter:
public <T extends Serializable & Cloneable> T getVar(Class<? super T> cls) {
return (T) cls.cast(val);
}
Note that in order to use T in the getter, we do need to have a parameter involving T.
Assuming we know a class Example implements Serializable, Cloneable, we can then use
// This actually ensures we get an instance of `Example` out:
Example e = instance.getVar(Example.class);
You can declare that type parameter in your class declaration, or method declaration, if that is a local variable, and use that type instead: -
public class Demo<T extends Interface1 & Interface2> {
private T t;
}
or: -
public class Demo {
public <S extends Interface1 & Interface2> void demo(S param1) {
S param;
}
}
If i understand your question correctly, you want a generic class which implements both the inetrfaces.
declare a generic type argument in your class definition and make it as an instace variable type.
public class Implementor<T extends Interface1<T> & Interface2<T>> {
private T t;
}
EDIT:
you cannot declare a type argument at instance variable declaration like
private <T extends I1 &I2> T t; //this cant be achieved.
at method level though is possible.
public <T extends I1 & I2> void method(T t){
}