首页 > 解决方案 > Java Color constructor casts long to float

问题描述

I was trying to draw gradients with Java (doesn't really matter what I was doing).

I have this line where it throws IllegalStatementException: Color parameter outside of expected range: Red:

Color c = new Color(Math.round(col1r), Math.round(col1g), Math.round(col1b));

col1r, col1g and 'col1b' are all doubles and are in range 0-255. Math.round() function returns long. While I expected it cast to int and use Color(int r, int g, int b) as constructor, it is cast to float and uses Color(float r, float g, float b) as constructor.

What is the reason for that?

P.S. I don't want a solution to get my program running, I can do that myself.

标签: javacasting

解决方案


Because the specs say so: JLS §5.1.2.

Going from long to int is considered a narrowing primitive conversion. As in, it is considered that as a general principle (even if it doesn't apply in some specific case), long -> int is 'lossy'. Therefore, java will not do so unless you explicitly ask for it. Even in this trivial example where we don't have multiple overloads:

public void foo(int x) {}

long y = 5;
foo(y); // this will not compile

To ask for it, you either [A] cast: foo((int) y); would have worked, or [B] use an operation+assignment operator: int x = 0; x += someLong; actually works, this is a bit weird but, hey, the spec says so.

However, going from long to double or float is a so-called Widening primitive conversion: It is considered lossless (eventhough that is not technically true; if your long is larger than 2^52 or smaller than -2^52 you may lose precision when converting a long to a double, for example) - and java will do that silently, there is no need to ask for it:

public void foo(double x) {}

long y = 5;
foo(y); // compiles just fine

Given the above, of all the various constructors that Color has, only Color(double, double, double) unambiguously and without needing to apply narrowing primitive conversion (which java won't do without you asking for it explicitly) fits given 3 longs for an argument.


推荐阅读