Get an instance of class <T> [runtime marker]

I create a Preferences class, and for Getters I do not use a Runtime type token.

So here is my getter method:

public <T> T get(String key, Class<T> clazz) { // do some crazy stuff (eg Double <-> Float) } 

Before that, everything works fine. But I would like the class parameter to be optional.

 boolean b = preferences.get(key); 

Therefore, I am adding an additional method:

 public <T> T get(String key) { // return get(key, Class<T>); } 

Now the question is: Is there a way to do this? Is there any way to get / instance of Class<T> .

Perhaps with a small workaround:

 public <T> T get(String key, T... args) { return get(key, (Class<T>) args.getClass().getComponentType()); } public <T> T get(String key, Class<T> clazz) { System.out.println("key : " + key); System.out.println("clazz: " + clazz); } // using Boolean b = get("mykey"); 
+6
source share
5 answers

This is possible with a small workaround.

 public <T> T get(String key, T... args) { return get(key, (Class<T>) args.getClass().getComponentType()); } public <T> T get(String key, Class<T> clazz) { System.out.println("key : " + key); System.out.println("clazz: " + clazz); } // using Boolean b = get("mykey"); 

Jep I don't like varargs either, but it still works.

+3
source

You can not. But if you want the class parameter to be optional, just pass null and check if it is invalid when using it.

If you want to do this on the left side, this is not possible.

+3
source

Not. General type information is stored in the calling method, the compiled T get(String key) knows only that it is general, but has no way of knowing which specific type was used to call it.

 //code public <T> T get(String key) //calling code Integer value = get("value"); //once compiled public Object get(String key) //calling code Integer value = (Integer) get("value"); 
+2
source

You might have this code:

 Integer i = getPref("integer"); System.out.println(i); @SuppressWarnings("unchecked") static <T> T getPref(String x) { return (T)properties.get(x); } 

Here the type <T> really derived from the left side. Keep in mind that this only helps you avoid the obvious devastation of Integer - for me personally, this is enough, and I often use such animals. Another thing to keep in mind is that Java type output is pretty lame, and you won't be able to get getPref as an argument to another method and enter the type of the argument.

+2
source

You cannot, but ...

Instead of overloading through generics, consider this template:

 public boolean getBoolean(String key) { // boolean impl here } public float getFloat(String key) { // float impl here } // etc 

Not only easier to code, but also easier to use - at least you know which types are acceptable.
With your current code, this will compile:

 SomeUnsupportedClass x = preferences.get("foo", SomeUnsupportedClass.class); 

but it will explode at runtime because you do not have code to support it.

By the way, this is bad: you want to catch problems at the time of coding, and not at run time.

+1
source

Source: https://habr.com/ru/post/916450/


All Articles