1

I wrote the following code but get the following compile error:

The local variable dirArrow may not have been initialized. Note that a problem regarding missing 'default:' on 'switch' has been suppressed, which is perhaps related to this problem

//return the ID of the robot and arrow of his facing direction
public String toString(){
    char dirArrow;
    switch (direction) {
        case UP: dirArrow= '^';
        case RIGHT: dirArrow= '>';
        case DOWN: dirArrow= 'V';
        case LEFT: dirArrow= '<';
        break;

    }
    return (Integer.toString(RoboID) + dirArrow);
}
tutak
  • 1,120
  • 1
  • 15
  • 28
Yuval Levy
  • 2,397
  • 10
  • 44
  • 73
  • 4
    add a `default` case after your last case, as the error message says. Also you should use `break` after every `case` or else it will fall-through. – QBrute Apr 29 '14 at 11:23
  • default in switch is not strictly necessary, in your case I would probably just omit myself. – kviiri Apr 29 '14 at 11:27
  • 1
    4 answers which *all* recommend initializing a `char` variable with a `null` value? Yikes! – Jon Skeet Apr 29 '14 at 11:29
  • 1
    And now most of the answers have changed to try using `''` which isn't a valid character literal either. Yikes. – Jon Skeet Apr 29 '14 at 11:37

6 Answers6

2

You need to initialize your dirArrow variable like:

char dirArrow = ' ';
switch (direction) {

Read why local variable should be initialized.

Note: also you need to add a break statement to the end of each case block like:

case UP: {
    dirArrow= '^';
    break;
}
Community
  • 1
  • 1
Salah
  • 8,567
  • 3
  • 26
  • 43
1

You have two problems there

  1. You haven't initialize the method local variable dirArrow, initialize it like char dirArrow = ' ';

  2. You don't have break at the end of each case. If you don't add break at the end of each case, for the first case, it will run all the case statements below that.


switch (direction) {
        case UP: dirArrow= '^'; break;
        case RIGHT: dirArrow= '>'; break;
        case DOWN: dirArrow= 'V'; break;
        case LEFT: dirArrow= '<'; break;

}
Hello World
  • 944
  • 2
  • 15
  • 39
Abimaran Kugathasan
  • 31,165
  • 11
  • 75
  • 105
0

its very much clear from the error that you have to initialize the local variable like '' like

char dirArrow='';
SpringLearner
  • 13,738
  • 20
  • 78
  • 116
0

either initialise the variable at declaration: char dirArrow = 0; or add a default block:

switch (direction) {
    case UP: dirArrow= '^';
    case RIGHT: dirArrow= '>';
    case DOWN: dirArrow= 'V';
    case LEFT: dirArrow= '<';
    break;
    defalut: dirArrow = 0;
}

BTW: for your code to work as expected, you should add a break after each case statement:

switch (direction) {
    case UP: dirArrow= '^';    break;
    case RIGHT: dirArrow= '>'; break;
    case DOWN: dirArrow= 'V';  break;
    case LEFT: dirArrow= '<';  break;

    defalut: dirArrow = 0;
}
iPirat
  • 2,197
  • 1
  • 17
  • 30
0

You haven't said what you want to happen if the direction isn't any of those values. Maybe that's currently the full set of directions, but in the future it may not be - and fundamentally the Java compiler doesn't check that you've covered every enum possibility. (You're also missing break statements, as noted by other answerers.)

Personally I'd change the approach and get rid of the switch entirely: add a toChar method to Direction, and then you can just use:

return Integer.toString(RoboID) + direction.toChar();

Your enum constructor would take the character to use as well, so it would be very easy to implement.

Much cleaner, IMO. The only downside is that it ties your character representation to the Direction enum which may be intended to be UI-neutral. If that's the case, I'd have a Map<Direction, Character> instead, and you can use it very simply:

return Integer.toString(RoboID) + DIRECTION_CHARS.get(direction);

If you want to stick with the switch statement, I wouldn't add an initial value to the variable as others have suggested - I'd throw an exception in the default case:

@Override public String toString() {
    char dirArrow;
    switch (direction) {
        case UP:
            dirArrow= '^';
            break;
        case RIGHT:
            dirArrow= '>';
            break;
        case DOWN:
            dirArrow= 'V';
            break;
        case LEFT:
            dirArrow= '<';
            break;
        default:
            throw new IllegalStateException("Unexpected direction! " + direction);
    }
    return (Integer.toString(RoboID) + dirArrow);
}

That's assuming it really isn't valid to have a direction other than the ones you've listed. Now, if you add a direction and forget to update this method, you'll end up with an exception rather than silent bad data.

The reason to not use a "dummy" initial value for the variable is that it doesn't express your desired behaviour. If you were to describe the method to someone in words, you would never mention that value, unless you really have a default value (e.g. space), in which case it's absolutely the right way to go.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I think it should be like `doNothing` for `default`. Because other than specified keys none is an action key. – Ravinder Reddy Apr 29 '14 at 11:38
  • @Ravinder: It's not clear what you mean, but it looks to me like the OP *expects* `direction` to be one of those enum values. – Jon Skeet Apr 29 '14 at 11:40
  • Yes I understand that. But not sure, unless it is an action key, how OP is going to use the return value. – Ravinder Reddy Apr 29 '14 at 11:41
  • @Ravinder: So why would you assume that the right return value would be `doNothing`? If the system isn't in an expected state, I'd normally prefer an exception so I can find out about that quickly... – Jon Skeet Apr 29 '14 at 11:42
0

A better solution is to change the enum

enum Direction {
    UP("^"), DOWN("v"), LEFT("<"), RIGHT(">");
    public final String arrow;
    private Direction(String arrow) {
       this.arrow = arrow;
    }
}

// in your Robot class.
public String toString(){
    return RoboID + direction.arrow;
}

BTW I would use roboID for a field name.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130