10 Replies Latest reply: Aug 23, 2010 2:28 PM by 653909 RSS

    wildcard capture problem please help

    653909
      I have this method:
      public <T extends X> T getX(Class<T> klass)
      and the following client code:
      public void utilize(Class<?> klass){
                  
                  Object o;
                  if (X.class.isAssignableFrom(klass)) {
                      o = getX(klass);
                  } else {
                      o = whateverDefaultObject();
                  }
           // ...
      }
      The point is if the klass is a subclass of X then use the getX method.

      The problem is that I am getting an error stating: required class of X, found class of capture of ?



      How can this be solved ?
      In the client method body the klass is guaranteed to be correct because of the if clause.
      Any help is keenly appreciated. Thanks
        • 1. Re: wildcard capture problem please help
          EJP
          You have to cast it.
          • 2. Re: wildcard capture problem please help
            653909
            Yes I know. In fact I have solved this thing to the point it compiles. I actually have found 2 solutions that make it compile - that's the problem.

            The question is what should I cast it to.
            I would like to get a formal explanation from someone who understands generics well to see if I did it right. I am not sure.

            Please, tell me the cast expression.
            • 3. Re: wildcard capture problem please help
              thomas.behr
              All casts to Class<X> or Class<T>, T a subtype of X, satisfy the original method signature. Since you don't know the exact subtype, you should cast to Class<X>.

              Edited by: thomas.behr on Aug 23, 2010 2:21 PM

              Fixed sloppy wording.
              • 4. Re: wildcard capture problem please help
                653909
                Is (Class<? extends X>) correct, or rather (Class<X>) ?

                Both generate just an unchecked cast warning, and thus seem to work.
                • 5. Re: wildcard capture problem please help
                  thomas.behr
                  Strictly speaking Class<? extends X> is the correct one. However, when the cast is done at runtime, the generic type information is not available (and therefore cannot be checked). In other words, for all practical purposes it doesn't matter.
                  • 6. Re: wildcard capture problem please help
                    653909
                    I am asking, cos as a rule return types should not be generic, and thus I am using this logic for casting and assignment.
                    • 7. Re: wildcard capture problem please help
                      843793
                      javaUserMuser wrote:
                      I am asking, cos as a rule return types should not be generic, and thus I am using this logic for casting and assignment.
                      I don't think there is such a rule.

                      In any case, you should be using klass.asSubclass(X.class) in order to keep warnings out of your code.

                      With kind regards
                      Ben
                      • 8. Re: wildcard capture problem please help
                        653909
                        Well.. im not sure.. but I think Joshua Bloch has written about generics. I am sure of the rule itself.
                        • 9. Re: wildcard capture problem please help
                          thomas.behr
                          javaUserMuser wrote:
                          I am asking, cos as a rule return types should not be generic, and thus I am using this logic for casting and assignment.
                          javaUserMuser wrote:I am sure of the rule itself.
                          You are mistaken. It doesn't make sense for return types not being generic. The most common example I know is the "read-only" collection
                          public Collection<? extends SomeDataObject> getData();
                          It's really hard (read impossible) to provide compile-time read-only collections without specifying a generified return type here.

                          For examples in the JDK, just look at [Iterable.iterator()|http://download-llnw.oracle.com/javase/6/docs/api/java/lang/Iterable.html#iterator()] or [Class.newInstance()|http://download-llnw.oracle.com/javase/6/docs/api/java/lang/Class.html#newInstance()]. Especially the first one is a very strong argument for generified return types, else for-each loops wouldn't really be that useful.

                          Edited by: thomas.behr on Aug 23, 2010 6:58 PM

                          Looking at your original source code sample, I cannot help but feel I misunderstood what you mean by "return types should not be generic". I mean it doesn't get much more generic than your getX method's return type, does it?
                          • 10. Re: wildcard capture problem please help
                            653909
                            Hmm.. maybe I have not expressed myself very clearly or have misstated what the author of this thing meant, I will research it once again, and will post here then ..