views:

117

answers:

2

Assigning values without using usual notation like "this.<Double>getAnything(int flag)"

private <T> T getAnything(int flag) {
    Object o = null;
    if (flag==0)
        o=new String("NewString");
    else if (flag==1)
        o=new Double(0D);
    return (T)o;
}


private void someMethod() {
    String s = getAnything(0);
    Double d = getAnything(1);
}

in the past it was enough only a return object on the method and a simple cast onthe receiveing type, so with the lacking of generic notation on the receiver object it is much more similar and fast to write, any other hint on this?

+4  A: 

On typesafety

It's not clear what you're trying to do, but it should be pointed out that there's no typesafety what-so-ever in your code.

Double d = getAnything(0);
// compiles fine, but throws ClassCastException at run time

This defeats the purpose of using generics in the first place.

You introduced this unsafetiness when you wrote this statement:

return (T)o; // warning: Type safety: Unchecked cast from Object to T

Related questions

See also

  • Effective Java 2nd Edition, Item 24: Eliminate unchecked warnings

On Typesafe Heterogeneous Container

Perhaps you want something like what Josh Bloch calls the Typesafe Heterogeneous Container. Here's a quote from Neal Gafter's blog:

Here is a simple but complete example of an API that uses type tokens in the THC pattern, from Josh's 2006 JavaOne talk:

public class Favorites {

    private Map<Class<?>, Object> favorites =
        new HashMap<Class<?>, Object>();

    public <T> void setFavorite(Class<T> klass, T thing) {
        favorites.put(klass, thing);
    }
    public <T> T getFavorite(Class<T> klass) {
        return klass.cast(favorites.get(klass));
    }

    public static void main(String[] args) {
        Favorites f = new Favorites();
        f.setFavorite(String.class, "Java");
        f.setFavorite(Integer.class, 0xcafebabe);

        String s = f.getFavorite(String.class);
        int i = f.getFavorite(Integer.class);
    }
}

With this pattern you get type-safety; int i = f.getFavorite(String.class); does NOT compile (which is a good thing!).

See also


On autoboxing

Autoboxing is the implicit conversion from say primitive int to reference type Integer; autounboxing is the opposite conversion. The question as stated has nothing to do with autoboxing.

See also

Related questions

polygenelubricants
+1  A: 

I think you're confusing autoboxing with type inference.

Type inference is when the compiler can tell what type it should use on a generic method on its own, from the variables used when calling the method.

For example if you have the following method:

public <T extends SomeClass> T process(T obj) {
    // call some methods of SomeClass on obj to process it here
    return obj;
}

and then call it like:

SomeChildClass a = new SomeChildClass(); // SomeChildClass extends SomeClass
a = process(a);

the inferred type will be SomeChildClass;

The type can be inferred from the parameters or from the return type, as is in your example. But it's not always obvious to the compiler what type it should use. If that happens you can force the type by using the method this.<Double>getAnything(int flag) that you described. This usually happens in situations like this:

public <T> List<T> getSomeList() {
    // implementation
}

public void processList(List<SomeClass> list) {
     // implementation
}

and calling

processList(getSomeList()); // compiler error: cannot convert List<Object> to List<SomeClass>

In cases like this you may need to force the type parameter.

All this being said, please take into consideration everything that polygenelubricants said as well, as he makes some very good points regarding your code and explains what autoboxing is (it's related to primitive wrapper classes like Integer for int, and Double for double).

Andrei Fierbinteanu