3

I want a method that processes a list of any type that implements a particular interface.

public interface Encryptable {
    public void encrypt() throws Exception ;
}

class DomainClass implements Encryptable {

    String name ;

    public void encrypt() throws Exception {
        try {
            name = CryptoUtils.encrypt(name);
        } 
    }
}

This utility method can encrypt a List of any domain class that implements Encryptable.

public static void encryptList ( Collection<? extends Encryptable> listToEncrypt    ) {
    for ( Encryptable objToEncrypt: listToEncrypt ) {
        try {
            objToEncrypt.encrypt() ;
        } catch (Exception e) {
        }
    }
}

I wrote a test app and this appears to work. What concerns me is the Java keyword 'extends'. My classes do not extend Encryptable they implement it. Does what I've written really work or am I the victim of some sort of side effect of doing things wrong but getting the right answer.

user903724
  • 2,956
  • 4
  • 24
  • 27
  • 1
    You're doing the things right. This is covered in [Lesson: Interfaces and Inheritance](http://docs.oracle.com/javase/tutorial/java/IandI/index.html) from Oracle Java tutorial. – Luiggi Mendoza Aug 02 '13 at 14:43
  • http://stackoverflow.com/questions/10971888/implements-vs-extends-in-generics-in-java – StormeHawke Aug 02 '13 at 14:44

5 Answers5

4

You're doing it right. This is a little ambiguous, but yes you're right. But keep in mind that you can always use an interface instead of a class and then extends does makes sense.

m0skit0
  • 25,268
  • 11
  • 79
  • 127
4

As always, JLS has answer to this.

See Section 8.1.2 for grammer of generics Type Parameters:

TypeParameters:
    < TypeParameterList >

TypeParameterList:
    TypeParameterList , TypeParameter
    TypeParameter

And Section 4.4 for grammer of TypeParameter:

TypeParameter:
    TypeVariable TypeBoundopt

TypeBound:
    extends TypeVariable
    extends ClassOrInterfaceType AdditionalBoundListopt

AdditionalBoundList:
    AdditionalBound AdditionalBoundList
    AdditionalBound

AdditionalBound:
    & InterfaceType

You can see that it uses extends keyword for ClassOrInterfaceType, in TypeBound. Also see Section 4.5.1 for grammer of Type Arguments and Wildcards.

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
4

Yes, you're doing the right thing. You are using an upper-bounded wildcard, according to the docs:

To declare an upper-bounded wildcard, use the wildcard character ('?'), followed by the extends keyword, followed by its upper bound. Note that, in this context, extends is used in a general sense to mean either "extends" (as in classes) or "implements" (as in interfaces).

But you should be cautious when using multiple bounds with type Parameters. In multiple bounds type parameter you have to specify the class name first and then interfaces.

Prabhaker A
  • 8,317
  • 1
  • 18
  • 24
2

Yes. Here is a somewhat old but still valid explanation, written back when generics were first introduced.

Chris Bode
  • 1,265
  • 7
  • 16
1

You write it right. In Generics is only the keyword "extended" allowed, either you extend from a class or you implement an interface.

arjacsoh
  • 8,932
  • 28
  • 106
  • 166