简体   繁体   中英

Why can I parse an 8 digit hex into a Long, and convert it to an Integer, but not parse as an Integer directly?

I am trying to use ColorDrawable(int color) . This class only has an int constructor. Normally, you can do something like this:

ColorDrawable(0xFF8E8F8A)

But since I am getting my color as a String (6 hex digits, no alpha), I have to do this:

Long color = Long.parseLong("FF"+hexColorString, 16); // hexColorString like "8E8F8A"
ColorDrawable drawable = new ColorDrawable(color.intValue());

Why doesn't Integer.parseInt("FF"+hexColorString, 16) just return me a negative (effectively unsigned) int, instead of throwing a NumberFormatException ?

EDIT: A more succinct version of my question:

Why don't Long.parseLong("FF"+hexColorString, 16).intValue() and Integer.parseInt("FF"+hexColorString, 16) return the same value? The former works, but the latter gives me an Exception.

EDIT: I wasn't getting the correct color anyway, so I switched to the following method:

ColorDrawable drawable = new ColorDrawable(Color.parseColor("#FF"+hexColorString));

The value of 0xFF8E8F8A is > Integer.MAX_VALUE .

Since no overflow or underflow throws Exception s by design, it will interpret your value as Integer.MIN_VALUE instead, because Integer.MAX_VALUE + 1 shifts to Integer.MIN_VALUE .

So, Long.intValue will convert the value to int , which, with a given value of Integer.MAX_VALUE + x where x > 0 , will shift from Integer.MIN_VALUE , ie Integer.MIN_VALUE + x .

However, from Integer javadoc:

An exception of type NumberFormatException is thrown if any of the following situations occurs:

The first argument is null or is a string of length zero. [...] The value represented by the string is not a value of type int.

A value of 0xFF8E8F8A is not of type int , hence the NumberFormatException .

As a side-note, I'm pretty sure ColorDrawable constructor takes an int because it takes an id instead of a numerical representation of your color, but to be honest the documentation isn't quite clear on that.

See R.color documentation here .

Final note - credit goes to OP on this one.

You can use new ColorDrawable(Color.parseColor(yourHexString)) for a more convenient approach.

Because 0xFF8E8F8A is outside of integer range. Ie 0xFF8E8F8A == 4287532938 , and it is bigger than Integer.MAX_VALUE .

Assumption that 0xFF8E8F8A equals to -7434358 (the value you get when parsing via Long) is not correct, because you can parse negative hex values:

Integer.parseInt("-717076", 16);

So -0x717076 equals to -7434358 and unsigned representation of it is 0xFF8E8F8A .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM