• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

interface with two generic types, how to implement a generic method ?

 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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




Thank you for your help
 
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch

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.
 
Campbell Ritchie
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Is this part of an assignment?

The second code block is worse; it will compile, but with warnings:-

javac Q.java
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
           lr.add((T) elem.action(s));
                                 ^
 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
           lr.add((T) elem.action(s));
                                 ^
 required: T
 found:    Object
 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)
2 warnings

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.
 
Saloon Keeper
Posts: 15484
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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:
     
    reply
      Bookmark Topic Watch Topic
    • New Topic