Results 1 to 19 of 19
Like Tree1Likes
  • 1 Post By jim829

Thread: First time using generics. Incomparable type errors.

  1. #1
    kkid is offline Senior Member
    Join Date
    Jul 2012
    Posts
    241
    Rep Power
    3

    Default First time using generics. Incomparable type errors.

    I am trying to make a generic method that will replace the data type T with those number types usable with a Scanner object. However, whenever I try to compile, I get errors saying that a Byte/Integer/Double etc are found when only a type T is allowed. This is the beginning of my method. I can;t understand what is wrong with it.

    Java Code:
    public <T extends Number> T nextRanged(T lowerBound, T upperBound, boolean inclusive, String errorMessage){
    	// Holds program execution until user inputs a numeric value between the bounds. Prevents all other input without exception.
    	// Output data type determined by the type of the bounds.
    		T input = null;
    		try{
    			if(input instanceof Byte){
    				input = new Byte(internalScanner.nextByte());
    			}
    			else if(input instanceof Integer){
    				input = new Integer(internalScanner.nextInt());
    			}
    			else if(input instanceof Double){
    				input = new Double(internalScanner.nextDouble());
    			}
    			else if(input instanceof Short){
    				input = new Short(internalScanner.nextShort());
    			}
    			else if(input instanceof Float){
    				input = new Float(internalScanner.nextFloat());
    			}
    			else if(input instanceof Long){
    				input = new Long(internalScanner.nextLong());
    			}
    			else{
    				throw new java.lang.IllegalArgumentException("Input not a valid number type.");
    			}
    		}
    		catch(java.util.InputMismatchException e){
    			internalScanner.nextLine();     // Clears buffer
    			System.out.println(errorMessage);
    			input = next(lowerBound, upperBound, inclusive, errorMessage);      // Recursively runs method for ~infinite attempts
    		}
    T, I assume, is determined by the data type of the parameters of type T when called.


    The purpose of the method, in the end, will be to provide the nextXXX() functionality of a Scanner object but with built in validation procedures. I could easily do this by making a nextIntRanged(), nextDoubleRanged() etc methods, but this seems wasteful to me.



    EDIT: Silly Chrome spelling suggestions. I meant "incompatible type errors"!


    EDIT 2: Error example:

    ValidatedScanner.java:57: error: incompatible types
    input = new Byte(internalScanner.nextByte());
    ^
    required: T
    found: Byte
    where T is a type-variable:
    T extends Number declared in method <T>nextRanged(T,T,boolean,String)
    Last edited by kkid; 08-29-2014 at 02:26 PM.

  2. #2
    gimbal2 is offline Just a guy
    Join Date
    Jun 2013
    Location
    Netherlands
    Posts
    4,090
    Rep Power
    6

    Default Re: First time using generics. Incomparable type errors.

    Difficult one to explain. Let me try.

    A cow is an animal. But an animal is not always a cow.

    Translating to your code.

    T is a Number. But Number is not always a T.

    Byte is a Number. But even though T must extend Number, Byte is not necessarily of type T. Hence your compile error. Besides that there is another huge flaw in the code:

    Java Code:
    T input = null; // null
    
    if(input instanceof Byte){ // null instanceof Byte? That will never happen
                    input = new Byte(internalScanner.nextByte());
                }
    "Syntactic sugar causes cancer of the semicolon." -- Alan Perlis

  3. #3
    kkid is offline Senior Member
    Join Date
    Jul 2012
    Posts
    241
    Rep Power
    3

    Default Re: First time using generics. Incomparable type errors.

    Quote Originally Posted by gimbal2 View Post
    Difficult one to explain. Let me try.

    A cow is an animal. But an animal is not always a cow.

    Translating to your code.

    T is a Number. But Number is not always a T.

    Byte is a Number. But even though T must extend Number, Byte is not necessarily of type T. Hence your compile error. Besides that there is another huge flaw in the code:

    Java Code:
    T input = null; // null
    
    if(input instanceof Byte){ // null instanceof Byte? That will never happen
                    input = new Byte(internalScanner.nextByte());
                }
    So part of my problem is that input just didn't really have a data type?

    In that case, I changed the input declaration like so:

    Java Code:
    T input = lowerBound;    // or upperBound, not really important
    My reasoning behind this is that as I want the data type to be determines by the data-type of the parameters entered, this would then trigger the correct scanner method as input now had that type.


    My compiler error was identical though. Am I going about this completely wrong?

  4. #4
    gimbal2 is offline Just a guy
    Join Date
    Jun 2013
    Location
    Netherlands
    Posts
    4,090
    Rep Power
    6

    Default Re: First time using generics. Incomparable type errors.

    Just to note: I read your reply, I want to answer and I've been trying to for the last 15 minutes, but I can't formulate something that might help you understand better unfortunately. I will respond to that last question:

    Am I going about this completely wrong?
    Well yes, you're creating uber-abstract, over-generalized code here. I'm impressed that you got as far as you did. Perhaps start simpler and start with a version that doesn't work with a generic type T, but rather just works with the Number base class. When you have that working, go from there. Tiny steps.
    Last edited by gimbal2; 08-29-2014 at 08:40 PM. Reason: wrong tags, derp
    "Syntactic sugar causes cancer of the semicolon." -- Alan Perlis

  5. #5
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,562
    Rep Power
    25

    Default Re: First time using generics. Incomparable type errors.

    T, I assume, is determined by the data type of the parameters of type T when called.
    I'm not sure about this. I think the data type is assigned when the code is compiled.
    If you don't understand my response, don't ignore it, ask a question.

  6. #6
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,777
    Rep Power
    5

    Default Re: First time using generics. Incomparable type errors.

    Your correct Norm. The phrase "when called" implies a run time operation. But by then, the generic type information
    has been erased and is not available at run time.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  7. #7
    kkid is offline Senior Member
    Join Date
    Jul 2012
    Posts
    241
    Rep Power
    3

    Default Re: First time using generics. Incomparable type errors.

    Quote Originally Posted by gimbal2 View Post
    Just to note: I read your reply, I want to answer and I've been trying to for the last 15 minutes, but I can't formulate something that might help you understand better unfortunately. I will respond to that last question:



    Well yes, you're creating uber-abstract, over-generalized code here. I'm impressed that you got as far as you did. Perhaps start simpler and start with a version that doesn't work with a generic type T, but rather just works with the Number base class. When you have that working, go from there. Tiny steps.


    ok, so I should make methods like:

    Java Code:
    public Number nextNumberRanged(Number lowerBound, Number upperBound)
    ?

    In that case, how would I distinguish between the different Scanner methods that have to be called?
    e.g. nextLong(), nextInt() etc...

  8. #8
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,777
    Rep Power
    5

    Default Re: First time using generics. Incomparable type errors.

    If you do it with generics like you first did, you don't need to cast the return value. And the passed values must match
    the return value or it won't compile. If you use Number, you must cast the return value to the appropriate type. Here are two examples (note
    that they are incomplete in terms of actual functionality but demonstrate the syntax for possible solutions).

    Java Code:
    public class GenericExample {
       public static void main(String[] args) {
          Integer a = nextRangeV1(20);
          Double b = nextRangeV1(20.0);
          Long c = nextRangeV1(20.0f); // won't compile
          
          Integer aa = (Integer)nextRangeV2(20);
          Double bb = (Double)nextRangeV2(20.0);
          Long cc = (Long)nextRangeV2(20.0f);  // runtime cast exception - Float to Long
       }
       @SuppressWarnings("unchecked")
       public static <T extends Number> T nextRangeV1(T lowerBound) {
          Scanner internalScanner = new Scanner(System.in);
          T input = null;
          if (lowerBound instanceof Integer) {
             input = (T) new Integer(internalScanner.nextInt());
          }
          else {
             throw new IllegalArgumentException("Unsupported Type");
          }
          return input;
       }
       
       public static Number nextRangeV2 (Number lowerBound) {
          Scanner internalScanner = new Scanner(System.in);
          Number input = null;
          if (lowerBound instanceof Integer) {
             input = (Integer) new Integer(internalScanner.nextInt());
          }
          else {
             throw new IllegalArgumentException("Unsupported Type");
          }
          return input;
       }
    }
    One final note: Notice I cast the input to (T) in the generic version. This caused an unchecked warning which
    I suppressed. There is nothing wrong with this as long as you, the coder, can guarantee that the cast will always
    be legal at runtime. This is a case where the coder has more insight that the compiler.

    And to paraphrase what Gimbal2 said, write code that not only you understand but those who must debug
    or modify it will probably understand.

    Regards,
    Jim
    kkid likes this.
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  9. #9
    kkid is offline Senior Member
    Join Date
    Jul 2012
    Posts
    241
    Rep Power
    3

    Default Re: First time using generics. Incomparable type errors.

    Thanks for that code Jim, really helpful. I am trying to go down the generics route (Partly merely to learn them, as I said, I've never used them before). In this case, my main problem was that I was casting in the wrong place? I should have been casting when creating my new wrapper objects? I did this and compilation goes past all the main generics stages.


    My main compilation issue now is that I cannot do any comparisons. I have:

    Java Code:
    input.compareTo(lowerBound)
    as one of my validation checks, but the compiler says that it cannot find a compareTo method from T objects (Even though all the wrapper classes have a compareTo() method, right?

    Any ideas how to go about solving this?

  10. #10
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,562
    Rep Power
    25

    Default Re: First time using generics. Incomparable type errors.

    What data type is the variable: input?
    If you don't understand my response, don't ignore it, ask a question.

  11. #11
    kkid is offline Senior Member
    Join Date
    Jul 2012
    Posts
    241
    Rep Power
    3

    Default Re: First time using generics. Incomparable type errors.

    Quote Originally Posted by Norm View Post
    What data type is the variable: input?
    T, with T being an extension of Number.

  12. #12
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,562
    Rep Power
    25

    Default Re: First time using generics. Incomparable type errors.

    The compiler says: it cannot find a compareTo method for that class
    because there isn't one.
    If you don't understand my response, don't ignore it, ask a question.

  13. #13
    kkid is offline Senior Member
    Join Date
    Jul 2012
    Posts
    241
    Rep Power
    3

    Default Re: First time using generics. Incomparable type errors.

    Quote Originally Posted by Norm View Post
    The compiler says: it cannot find a compareTo method for that class
    because there isn't one.
    Oh, ooops. I thought it would look for methods of the classes T represents. As T does not actually exist, this means I can't do any method calls and thus can' do any comparisons?

    EDIT: Found a way, I think, I added "& Comparable<? extends T>"
    Last edited by kkid; 08-30-2014 at 04:27 PM.

  14. #14
    kkid is offline Senior Member
    Join Date
    Jul 2012
    Posts
    241
    Rep Power
    3

    Default Re: First time using generics. Incomparable type errors.

    UPDATE: working fully now, exactly how I wanted. I've managed to accomplish the same thing using only about 1/6th of the code by utilising generics!

    Thank you for all your help everyone.

  15. #15
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,777
    Rep Power
    5

    Default Re: First time using generics. Incomparable type errors.

    If you want to try some additional stuff you could use reflection. You can derive the scanner method from the passed
    type so you get rid of all the instanceof tests. I am not recommending this for production code because I have read
    that reflection incurs additional overhead (and it can obfuscate what one is trying to do - violates the KISS principle).
    But its a worthwhile exercise to try it.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  16. #16
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,654
    Blog Entries
    7
    Rep Power
    21

    Default Re: First time using generics. Incomparable type errors.

    imho, people are funny w.r.t. to Reflection; i.e. they all claim it's ABT (A Bad Thing (tm)) while they all admire, say, DI (Dependency Injection) while DI is Reflection all over the place. Back to the subject: generics allows you to 'instantiate' a class or method with an unknown type, but the instantiation has one type only; i.e. T extends Number is one type, it could be Byte or Int or Long, but only one of them; you can't have them all in one single method. If you want them all, the method has to return a Number and you don't need generics for that ...

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  17. #17
    gimbal2 is offline Just a guy
    Join Date
    Jun 2013
    Location
    Netherlands
    Posts
    4,090
    Rep Power
    6

    Default Re: First time using generics. Incomparable type errors.

    The difference being that dependency injection is reflection without the hard to maintain boiler plate code ;) Most of anything frameworky-automaty in Java is done with Reflection, its the most wonderful and magical tool in the toolbox. To use in tools and frameworks where it is nice and hidden away, not to make your application code unreadable with.
    "Syntactic sugar causes cancer of the semicolon." -- Alan Perlis

  18. #18
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,654
    Blog Entries
    7
    Rep Power
    21

    Default Re: First time using generics. Incomparable type errors.

    Quote Originally Posted by gimbal2 View Post
    The difference being that dependency injection is reflection without the hard to maintain boiler plate code ;) Most of anything frameworky-automaty in Java is done with Reflection, its the most wonderful and magical tool in the toolbox. To use in tools and frameworks where it is nice and hidden away, not to make your application code unreadable with.
    So if you don't see it, it's AGT (A Good Thing)? Don't get me wrong: I like Reflection; it's the operating theatre of Java, where you can see the intestines of your classes and do with them what you want ;-)

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  19. #19
    gimbal2 is offline Just a guy
    Join Date
    Jun 2013
    Location
    Netherlands
    Posts
    4,090
    Rep Power
    6

    Default Re: First time using generics. Incomparable type errors.

    If you don't see it, it is not a bad thing I'd say.
    "Syntactic sugar causes cancer of the semicolon." -- Alan Perlis

Similar Threads

  1. Replies: 81
    Last Post: 12-23-2011, 10:01 AM
  2. Run-time errors
    By MostinCredible21 in forum New To Java
    Replies: 6
    Last Post: 10-01-2011, 09:49 AM
  3. Run time errors
    By crabman in forum New To Java
    Replies: 6
    Last Post: 10-11-2009, 09:51 PM
  4. ArrayList<type> - Generics
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 11-14-2007, 03:21 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •