Hello, i'm sorry if my question isn't clear. I'm not sure how to formulate it correctly.
I have this piece of code where XXXX must be replaced by a type.
In that code, we're calling action of elem which is T type then I'm deducing that T must extends Membre
This is what I tried to do, there is no error when I run the program however I have to cast (T) to elem.action and I don't want to do that, there is something wrong in the way I declared the generic in the method
I couldn't get your first code block to compile. The two classes are completely independent of each other, so the interface Membre is a red herring. Because your generic method takes the type XXXX, it cannot identify the generic type T for your List.
posted 2 months ago
Is this part of an assignment?
The second code block is worse; it will compile, but with warnings:-
Note: Q.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
[critchie@xxx ~]$ javac -Xlint:unchecked Q.java
Q.java:13: warning: [unchecked] unchecked call to action(S) as a member of the raw type Membre
where S,R are type-variables:
S extends Object declared in interface Membre
R extends Object declared in interface Membre
Q.java:13: warning: [unchecked] unchecked cast
where T,S are type-variables:
T extends Membre declared in method <T,S>apply(List<T>,S)
S extends Object declared in method <T,S>apply(List<T>,S)
That means it is possible for such code to fail at runtime with an exception. Don't think your code is correct because it compiles completely. You should never use a raw type. The type of that method shouldn't be <T extends Membre>, but <T extends Membre<S, R>>. That recognises that Membre is parametrised itself; in that form there is no relationship between R, S, and T. That means the compiler will recognise that the cast to T might not succeed and it will fail to compile.
There is a simpler way to make that method generic and add the correct types to your List. It will require something different for the generic parameter for your method.
As Campbell says, don't use raw types. That advice isn't limited to variable declarations, but also generic parameter declarations. In your declaration of T, you're using Membre as a raw type.
Let's break down what you're trying to do. From the code, it appears that you want to take a list of Membres, apply each Membre's action to s, and add the result to a new list.
It's clear that your code is not going to work, because you're casting the result of applying the action to T, which is almost certainly wrong. T is likely not the return type of the action method. The compiler would have told you about this if you hadn't used a raw type.
Instead, I assume this is what you want to do:
There are a few changes I made:
Renamed the classes, methods and variables so they are more easy to read.
Declared X and Y (or you could declare S and R), because you can't use them before you declare them.
Removed the T declaration, because you can declare all your variables in terms of X and Y.
Changed the type of the input list to Iterable. Don't use more specific types than you need.
Added upper and lower bounds to the functions variable, so the method can be used in a wider range of situations.
Removed the cast. Combining casts and generics is a sign of badly written code.
Used the diamond operator in the list creation.
If you're using Java 8 or higher, you can also replace the method body with functional code:
Cob is sand, clay and sometimes straw. This tiny ad is made of cob: