2

Can someone explain to me, how my method here in java that expects a int, but accepts '!' as an argument? further more, how can it interpet it as 33 when i debug it, but when i do System.out.println(Character.getNumericValue('!')); it prints -1?

here is the code guys:

public abstract class Stuff {

    public static char getCharacterFromNumber(int number) throws InvalidCharException {

        if(number>=20) {
            if (number <= 45) {
                switch (number) {
                    case 20:
                        return 'a';
                    case 21:
                        return 'b';
                    case 22:
                        return 'c';
                    case 23:
                        return 'd';
                    case 24:
                        return 'e';

                    case 25:
                        return 'f';
                    case 26:
                        return 'g';
                    case 27:
                        return 'h';
                    case 28:
                        return 'i';
                    case 29:
                        return 'j';

                    case 30:
                        return 'k';
                    case 31:
                        return 'l';
                    case 32:
                        return 'm';
                    case 33:
                        return 'n';
                    case 34:
                        return 'o';

                    case 35:
                        return 'p';
                    case 36:
                        return 'q';
                    case 37:
                        return 'r';
                    case 38:
                        return 's';
                    case 39:
                        return 't';

                    case 40:
                        return 'u';
                    case 41:
                        return 'v';
                    case 42:
                        return 'w';
                    case 43:
                        return 'x';
                    case 44:
                        return 'y';
                    case 45:
                        return 'z';
                }
            }
        }
        throw new InvalidCharException();
    }

    public static void main(String [] args){
        try {
            System.out.println(Stuff.getCharacterFromNumber('!'));
        } catch (InvalidCharException e) {
            e.printStackTrace();
        }
        System.out.println(Character.getNumericValue('!'));
    }
}

i have searched but havent found anything similar to my problem, and if someone has a better idea for the title i'd appricate it :)

takendarkk
  • 3,347
  • 8
  • 25
  • 37
mozzie
  • 17
  • 5
  • Because single quotes indicate a `char` which can be used as a number. – takendarkk Feb 01 '18 at 20:43
  • that i can understand, but how can it be both -1 and 33? and if it is -1 shouldn't my if statement stop it and throw an exception? – mozzie Feb 01 '18 at 20:45
  • Try reading [Character.getNumericValue() issue](https://stackoverflow.com/questions/2148096/character-getnumericvalue-issue) or read the docs for that method which describe why you see what you see. – takendarkk Feb 01 '18 at 20:46
  • On a different note, consider something like `return (char) ('a' - 20 + number);` as opposed to the switch. – Zachary Feb 01 '18 at 20:58

2 Answers2

4

Character literals are nothing more than pure values, but with different types. 48 represents exactly the same value as '0' (though the first one is of a type int and the second one is of a type char). 49 also represents the same value as '1'. That's why 'a' + 1 will result in a value equal to 'b'.

What you are confused about is why this:

System.out.println(Character.getNumericValue('!'));

prints -1. Well, to find out why, let's jump into java docs. We can see that the method Character.getNumericValue:

Returns the int value that the specified character (Unicode code point) represents.

It does not return the Unicode value of a character. If you want to see what number represents the character literal '!' you might want to do it like so:

System.out.println((int)'!');

Which will print: 33.

Fureeish
  • 12,533
  • 4
  • 32
  • 62
  • 1
    "48 is exactly the same as '0'" - well, they're of different types. If you have two methods with the same name, one accepting `int` and one accepting `char`, then `foo(48)` and `foo('0')` won't do the same thing. I suggest you clarify your first sentence in this regard. – Jon Skeet Feb 01 '18 at 21:00
  • Thank you. I have edited the answer accordingly. You are right that in this kind of enviroment we need to be very specific in terms of which words and terms we use – Fureeish Feb 01 '18 at 21:05
3

The character '!' has an ASCII value of 33. Java allows for a char value to be widened to an int, which explains why you can pass a char into a method expecting an int.

However, Character.getNumericValue does something different.

Returns the int value that the specified Unicode character represents.

(bold emphasis mine)

That is '1' returns 1, whereas the ASCII code is 49. If the character doesn't represent a numeric value:

If the character does not have a numeric value, then -1 is returned.

You get 2 different values because the ASCII code and the numeric value are two different concepts.

rgettman
  • 176,041
  • 30
  • 275
  • 357