tags:

views:

149

answers:

5

I have a method that usually takes an item from a list and has a signature of:

myMethod(T item)

I want to use this method but I know what I am sending the method.

SpecificItem myItem = new SpecificItem();

myMethod((T) myItem);

This doesn't sit well with me. Is this a sign of bad code?

+9  A: 

myMethod is defined in a generic class, somewhat like:

public class MyClass<T> {
   T myItem;

   public void myMethod(T item) {
      // do Something with item
   }

   public T myOtherMethod() {
      myMethod(myItem);   // casting is not necessary
      return myItem;
   }

}

If you instantiate this class, you exchange the variable type T with a real one:

MyClass<SpecificItem > concreteClass = new MyClass<SpecificItem >();

And if you call myMethod on this instance, you have to provide a SpecificItem, because SpecificItem is the generic type for this instance.

(I'm not sure it my post answers your question, please comment so I can improve it)

Andreas_D
So if I have public interface myInterface<T>{ void myMethod(T item);}both T's have to match??
Lumpy
@Lumpy, yes, that's why they are both named "T". If you wanted multiple types, you could do myInterface<T,S> or so forth (see, e.g., Map)
Alex Feinman
Ok that makes a lot of sense thanks
Lumpy
+1  A: 

You might be looking for something like this:

class C<? extends T> {

   public void myMethod(T myItem) {
      ...
   }

}
Allain Lalonde
A: 

Probably better way would be to make SpecificItem a subclass of T or make T an interface and have SpecificItem implement it.

Drew
+2  A: 

It's better that you code to interface. For example :

In myMethod :

<T extends <? super Item>> void (T item);

This tells compiler to only accepts a generic type of T which is an implementation/extention of Item interface/class. This will make sure that given input is in correct type. Compiler guarantees it.

In main class :

Item myItem = new SpecificItem();

Code given above is the best practice. Get used to it. But (i discourage this) you can code like this too :

SpecificItem myItem = new SpecificItem();

You can read Java source code. For example in class java.util.Collections. In method sort(List) you may notice that Joshua Bloch makes sure that given input is always in correct format. To give it a try, do this :

public class Class1 {
    public static void main(String[] args) {
        List<Class1> list = new ArrayList<Class1>();

        Collections.sort(list);
    }
}

Above code will produce compilation error. To fix this compilation error Class1 must implement interface Comparable. This maintains the precondition of method sort(List) which assumes that given input is a List of Comparable.

Oh i almost forget about your question. Actually it's not a bad code since it works. I just want to tell you that there is a better way to do that.

jancrot
+1  A: 

The way you call the method looks strange. If you have declared your generic method as

public <T> void myMethod(T item);

the compiler knows, that T is some abstract type and you shouldn't need to cast an input parameter to it. Just make sure, that T is not declared as some specific type in your code.

upd: look here for an example: Generics/Usinggenericmethodstoprintarrayofdifferenttypes.htm">http://www.java2s.com/Tutorial/Java/0200_Generics/Usinggenericmethodstoprintarrayofdifferenttypes.htm

D_K