how to get the persistent class parameter of a class generic? <T> - java

here's my code:
AbstractClass
public abstract class AbstractClass<T>{
public abstract Class<?> getPersistentClass();
public void invokeNothing(){
Class<T> c = getPersistentClass();
// do something....
// some code...
}
}
CommonClass
public class CommonClass<T> extends AbstractClass<T>{
public Class<?> getPersistentClass(){
// how to get the persistent class of generic T
// T.class
return // T.class
}
}
Service
public class CommonService{
#Autowired
private CommonAbstractClass<Person> commonClass;
public void invoke(){
commonClass.invokeNothing();
}
}
how to get the persistent class parameter of a class generic? in my class CommonClass in method getPersistentClass();
please help me thanks...

Actually there is no way (at least no easy way I am aware of except reflection in some cases) to get the runtime type of the generic type parameter due to type erasure. You can use the following safe work-around:
public class CommonClass<T>{
private final Class<T> type;
public CommonClass(Class<T> type) {
this.type = type;
}
public Class<T> getMyType() {
return this.type;
}
}
But you may need to instantiate it like:
CommonClass<Person> cp = new CommonClass<Person>(Person.class);
If you are using Spring you can find this answer useful.

Related

Java Generic Setter with Interface and Abstract Class

i have a problem with an Interface and generic setters that i tried to solve for some hours now.
i have an interface where i want to define some getter and setter functions. the getter functions should be implemented by some abstract class since they usually shouldn't change.
the setter functions on the other hand should be overrideable multiple times by a defined class. In the case i try to describe it would be that the childClass should be able to implement 2 setFunctions with the same name and different input values
Interface TestClass {
public abstract void setSomething(List<?> value);
public abstract List<String> getSomething();
}
abstract class AbstractTestClass implements TestClass {
List<String> someData;
public List<String> getSomething() {
return someData;
}
}
class TestClassImplementation extends AbstractTestClass() {
#Override
public void setSomething(List<String> data) {
someData = data;
}
#Override
public void setSomething(List<SomeOtherType> data) {
someData = convertToStringList(data);
}
private List<String> convertToStringList(List<SomeOtherType> data) {
... do some conversion ...
return returnList;
}
}
hope this gives the idea of what i want to do. I would even prefer to implement the setSomething with the stringlist in the abstract class. But both setters must be reachable.
Thanks
You simply can't do that. Generics are not retained at runtime (google type erasure for more infos on this or just read the wikipedia page).
This means that your setSomething-methods all have the same signature, as their only parameter is of type List.
Well, you should try with generic solution:
Interface TestClass<T> { //Generic type T that you will provide when extending with actual class
public abstract void setSomething(List<T> value);
public abstract List<T> getSomething();
}
class TestClassImplementation extends AbstractTestClass<RealType> {
#Override
public void setSomething(List<RealType> data) {
someData = data;
}
}
The thing that confuses you is that the wildcard sign ? does not mean it changes any type, it just denotes an unknown type.

Get actual enum class of the Parameterized class T extends Enum<?>

I have a class:
public class MultipleSorting<T extends Enum<?>> {
private T criteriaType;
public Class<T> getCriteriaClass() {
Field field = ReflectionUtils.getField(getClass(),"criteriaType");
ReflectionUtils.makeAccessible(field);
return (Class<T>)field.getType();
}
}
This class is get instantiated as:
public abstract class MultiSortPageableController<T extends MultiSortPageableController<?,?>, U extends Enum<?>> {
private MultipleSorting<U> multipleSorting;
public MultiSortPageableController() {
super();
multipleSorting = new MultipleSorting<U>();
}
}
The actual value of U is passed from the child class of MultiSortPageableController which is:
public abstract class AbstractArticleSearchController<T extends AbstractArticleSearchController<T>> extends MultiSortPageableController<T,ArticleSortField> {
}
The ArticleSortField is an Enum.
I was expecting the method getCriteriaClass of MultipleSorting would return ArticleSortField from a method of MultiSortPageableController. But it is returning java.lang.Enum.
I am unable to figure it out why it is not returning the actual enum and how can I make it so. Any pointer would be very helpful to me. I need to get ArticleSortField.
Purpose:
I two requirement:
To get the actual class of enum type (say ArticleSortField.class)
To list enum value. If I have the enum class, then I could invoke class..getEnumConstants().
Java compiler removes information about generics, therefore when you use reflection you get no information about the declared type, other than Enum. This process is called type erasure.
How about passing the type down, via the constructor, like this:
public class MultipleSorting<T extends Enum<?>> {
private Class<T> criteriaType;
MultipleSorting(Class<T> criteriaType) {
this.criteriaType = criteriaType;
}
public Class<T> getCriteriaClass() {
return criteriaType;
}
}
public abstract class MultiSortPageableController<T extends MultiSortPageableController<?, ?>, U extends Enum<?>> {
private MultipleSorting<U> multipleSorting;
public MultiSortPageableController(Class<U> criteriaType) {
super();
multipleSorting = new MultipleSorting<U>(criteriaType);
}
}
public abstract class AbstractArticleSearchController<T extends AbstractArticleSearchController<T>> extends MultiSortPageableController<T, ArticleSortField> {
public AbstractArticleSearchController() {
super(ArticleSortField.class);
}
}

Call base constructor with different arguments than subclass constructor

I'm sure this is a duplicate, but the keywords for my search are too common... I get a lot of hits, for things I'm not looking for. I'm coming from C#, and Java generics seem to be a bit behind the .NET implementation, so this is pretty frustrating for me.
I have an abstract class BaseRepository like so:
public abstract class BaseRepository<T, K> implements Repository<T, K> {
private Class<T> type;
private Class<K> keyType;
public BaseRepository(Class<T> clazz, Class<K> kClazz) {
type = clazz;
keyType = kClazz;
}
protected Class<T> getType() {
return type;
}
protected Class<K> getKeyType(){
return keyType;
}
}
Now I want to derive from my base class with an EmployeeRepository like so:
public class EmployeeRepository extends BaseRepository<Employee, UUID>{
}
With c#, I would not need to make such heroic efforts to instantiate the base class, but it seems java's implementation of generics requires you to pass the generic type(s) in the constructor.
So how do I create a parameterless constructor for my EmployeeRepository class that instantiates the base class with an entity type of Employee and a key type of UUID? I want to be able to write this:
EmployeeRepository foo = new EmployeeRepository();
... and have it instantiate the abstract class with Class<Employee> and Class<UUID>.
AFAIK, there is no way round this other than invoking the superclass constructor from the default subclass constructor thus:
public EmployeeRepository() {
super(Employee.class, UUID.class);
...
}
You could use reflection to determine the type of the generic arguments.
public abstract class BaseRepository<T, K> implements Repository<T, K> {
private Class<T> type;
private Class<K> keyType;
public BaseRepository() {
Type[] actualTypes = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments();
this.type = (Class<T>)actualTypes[0];
this.keyType = (Class<K>)actualTypes[1];
}
protected Class<T> getType() {
return type;
}
protected Class<K> getKeyType(){
return keyType;
}
}
However, the real question is: why do you want to have the types?
As an alternative, use the Builder pattern:
public class EmployeeRepository extends BaseRepository<Employee, UUID>{
public static EmployeeRepository newInstance() {
return new EmployeeRepository(Employee.class, UUID.class);
}
...
}
EmployeeRepository foo = EmployeeRepository.newInstance();

How to get the class of type variable in Java Generics

I've seen similar questions but they didnt help very much.
For instance I've got this Generic Class:
public class ContainerTest<T>
{
public void doSomething()
{
//I want here to determinate the Class of the type argument (In this case String)
}
}
and Another Class which uses this Container Class
public class TestCase
{
private ContainerTest<String> containerTest;
public void someMethod()
{
containerTest.doSomething();
}
}
Is it possible to determinate the Class of the type argument in method doSomething() without having an explicit type variable/field or any constructor in ContainerTest Class?
Update: Changed format of ContainerTest Class
The only way is to store the class in an instance variable and require it as an argument of the constructor:
public class ContainerTest<T>
{
private Class<T> tClass;
public ContainerTest(Class<T> tClass) {
this.tCLass = tClass;
}
public void doSomething()
{
//access tClass here
}
}
If you are interested in the reflection way, I found a partial solution in this great article: http://www.artima.com/weblogs/viewpost.jsp?thread=208860
In short, you can use java.lang.Class.getGenericSuperclass() and java.lang.reflect.ParameterizedType.getActualTypeArguments() methods, but you have to subclass some parent super class.
Following snippet works for a class that directly extends the superclass AbstractUserType. See the referenced article for more general solution.
import java.lang.reflect.ParameterizedType;
public class AbstractUserType<T> {
public Class<T> returnedClass() {
ParameterizedType parameterizedType = (ParameterizedType) getClass()
.getGenericSuperclass();
#SuppressWarnings("unchecked")
Class<T> ret = (Class<T>) parameterizedType.getActualTypeArguments()[0];
return ret;
}
public static void main(String[] args) {
AbstractUserType<String> myVar = new AbstractUserType<String>() {};
System.err.println(myVar.returnedClass());
}
}
There is no "clean" way to get the Generic Type argument from within the class.
Instead, a common pattern is to pass the Class of the Generic Type to the constructor and keep it as an inner property juste as done in the java.util.EnumMap implementation.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/EnumMap.html
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/EnumMap.java
public class ContainerTest<T> {
Class<T> type;
T t;
public ContainerTest(Class<T> type) {
this.type = type;
}
public void setT(T t) {
this.t = t;
}
public T getT() {
return t;
}
public void doSomething() {
//There you can use "type" property.
}
}
No. It is not possible because of type erasure (the type parameters are compiled as Object + type casts). If you really need to know/enforce the type in runtime you may store a reference to a Class object.
public class ContainerTest<T> {
private final Class<T> klass;
private final List<T> list = new ArrayList<T>();
ContainerTest(Class<T> klass) {
this.klass = klass;
}
Class<T> getElementClass() {
return klass;
}
void add(T t) {
//klass.cast forces a runtime cast operation
list.add(klass.cast(t));
}
}
Use:
ContainerTest<String> c = new ContainerTest<>(String.class);
There is a way to get the runtime type of the type parameter by using Guava's TypeToken to capture it. The solution's disadvantage is that you have to create an anonymous subclass each time you need an instance of Container.
class Container<T> {
TypeToken<T> tokenOfContainedType = new TypeToken<T>(getClass()) {};
public Type getContainedType() {
return tokenOfContainedType.getType();
}
}
class TestCase {
// note that containerTest is not a simple instance of Container,
// an anonymous subclass is created
private Container<String> containerTest = new Container<String>() {};
#Test
public void test() {
Assert.assertEquals(String.class, containerTest.getContainedType());
}
}
The key of this solution is described in tha JavaDoc of TypeToken's constructor used in the code above:
Clients create an empty anonymous subclass. Doing so embeds the type parameter in the anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.
If You can define like this
public class ContainerTest<T>
{
public void doSomething(T clazz)
{
}
}
Then it is possible

Return the type of a java class implementing an interface

I have a flag telling me which class type to use. A static method should be used to retrieve the right class. The class type is needed as an input for a generic method.
public class Config{
public static int flag = 1;
}
public interface A {
public abstract int getResult();
}
public class A1 implements A{
public int getResult{
// ...
}
}
public class A2 implements A{
public int getResult{
// ...
}
}
public class AType{
public static Class getType(){
switch (Config.flag) {
case 1:
return A1.class;
case 2:
return A2.class;
default:
return null;
}
}
The return type of "getType()" is wrong. I already tried some generic return types, but as it seems it does not work like that to retrieve a class type for further usage...
Any ideas how to return a different class type depending on a configuration flag?
I need the class type (A1 or A2) as an input for generic methods like this one:
public static <T extends Message> T[] getArrayFromStream(DataInputStream in, Class<T> returnType)
throws IOException {
return getArrayFromStream(in, returnType, new Object[0]);
}
My guess (given the lack of information) is that you are trying to do this:
Class clazz = getType();
A instance = clazz.newInstance();
If that is the case you need this...
public Class<? extends A> getType(){...}
and then
Class<? extends A> clazz = getType();
A instance = clazz.newInstance();

Categories

Resources