Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

  • Common Java Mistakes: Type Mismatch/Invalid Cast

    Problem description: Type Mismatch/Invalid Cast
    Problem category: Compile-Time Problem

    Diagnosis Difficulty: Easy
    Difficulty to Fix: Easy


    This problem usually occurs when you're trying to perform calculations using floating point numbers and then storing the results into an integer data type. Java has no problem promoting the data type of a value implicitly, however the designers decided that because an implicit demotion/down cast is likely an accident, the programmer must explicitly specify that's what they want.

    The promotion diagram for Java data types looks like (follow the arrows for implicit promotions/casts):

    `
                    byte
                      v
                    short
                      v
                    int
                      v
                    long
                      v
                    float
                      v
                    double
                      v
          boolean > String < Object < Polymorphic object
                      ^
                    char

    So for example, a byte can be implicitly cast to a short, but a short cannot be implicitly cast to a byte. The most common problems for beginners is dealing with casting of primitive types (particularly between floating point data types and integer data types).

    Examples of some bad casts:
    // simple examples
    // 1
    int a = 5.5; // casting from double to int
    // 2
    long b = 1;
    int c = b; // casting from long to int
    // 3
    double d = 3;
    int e = d; // casting from double to int
     
    // more complex/subtle examples
    // 4
    double f = 5;
    int g = 1 + 3 * b; // casting from double to int
    // 5
    short h = 3; // casting from int to short
    // 6
    float i = 3.5; // casting from double to float
    byte

    Suggested fixes

    For most cases (especially those involving number data types) you can usually specify an explicit cast. This is done by placing the type name in parenthesis, then an expression you want casted after that.

    int a = (int) 5.5; // 5.5 is explicitly cast into an int, a=5

    Note that when dealing with polymorphic objects and casting them down the inheritance chain will still perform type checking. For example:

    public class Base
    {}
     
    public class Derive1 extends Base
    {}
     
    public class Derive2 extends Base
    {}
     
    //...
    Base a = new Derive1();
    Derive2 b = (Derive1) a; // technically should compile, however on runtime you'll get a ClassCastException. You'll probably even get a warning saying this is an unsafe cast.

    In the above example, the compiler cannot determine if a is a Derive1 object, a Derive2 object, or something else entirely.

    Additionally, sometimes a cast demotion does not exist, even though a promotion cast does exist (for example a String to an int).

    int a = (int) "5"; // invalid, there's no cast for a String to an int, implicit or explicit

    In these cases, you have 2 options:

    1. Search for a method which performs the desired option you want
    int a = Integer.parseInt("5"); // using the Integer class method parseInt to convert a String to an int
    2. Manually extract the data you want
    Point a = new Point(3,5);
    int xCoord = a.x;
    int yCoord = a.y;

    Number constants

    The last major problem when dealing with casts are number constants.
    float a = 3.5; // 3.5 is actually a double literal, invalid implicit cast
    int b = 3L; // 3 is actually a long literal, invalid implicit cast
    byte c = 256; // out of the range for a byte, treated as an int literal, invalid implicit cast

    There are two solutions to this problem:
    1. Use the "general" solution of specifying an explicit cast.
    float a = (float) 3.5;
    int b = (int) 3L;
    byte c = (byte) 256;
    2. Use the appropriate suffixes (or lack there-of) when specifying the literal type. These suffixes are:
    byte - none (must be in the range of a byte)
    short - none (must be in the range of a short)
    int - none (must be in the range of an int)
    long - 'L' (must be in the range of a long)
    float - 'f'
    double - none

    float a = 3.5f;
    int b = 3;
    long c = 1000000000000L;
    // there's no appropriate equivalent for this case since it's basically a guaranteed loss of precision
    // byte c = 256;
    This article was originally published in forum thread: Common Java Mistakes started by helloworld922 View original post