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");
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.
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");
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.
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.