Is there a way to get the Java compiler to produce an error when a "long" is implicitly converted to a "double", as this can cause data loss?
EDIT: The reason I cannot accept the answer from Alex, is that it defeats my purpose. What I want to do is create a minimal "functor" API, that does not cause garbage by directly supporting primitive types too, instead of only supporting object types using generics. But to keep the number of interfaces small, I want to use as few types as possible. With just double and Object, for parameters and return value, I support (almost) all types without causing garbage, nor loosing any data (boolean does not convert to double, but does not cause garbage by autoboxing either, AFAIK, so it's OK not to support it explicitly). Since all primitive types, except boolean and long, can safely, and implicitly be converted to double, I have almost all my needs covered.
That is where the question comes from: if I don't add explicit support for long in that API, how to prevent long being used at all, as it would leading to bugs? And of course, using java.lang.Double instead of double would cause garbage, and therefore make the API pointless.
Before anyone asks, I'll say that I want to use the API in real-time Android games where "garbage" is a real issue, unlike the JVM.
No, this is not possible. According to Java Language Specification, long
to double
is considered a widening conversion. It never triggers a compile or a run-time error.
(JLS, section 5.1.2) Despite the fact that loss of precision may occur, a widening primitive conversion never results in a run-time exception (§11.1.1).
Difficult and requiring some research.
The first idea - Byte Code
You could use byte code manipulation. There are some instructions like l2d
(long-to-double) that might be found.
Maybe combined with annotations.
Make your own annotation to suppress processing for this check. Do annotation processing.
The second idea - JavaME
Java ME which might forbid the use of doubles altogether.
The third idea - Java parsing and data analysis
Java compiler toolkit.
It is not possible to produce an error on implicit conversion, as stated in the other answer. If the overhead is acceptable, you can force an explicit check using autoboxing conversions by declaring a variable or method parameter as java.lang.Double
; the compiler will silently box primitive double
values but will throw a compile exception for long
expressions.
public class Doubles {
static double asDouble(Double d) {
return d.doubleValue();
}
public static void main(String[] args) {
long l = Long.MAX_VALUE;
double d = Double.MAX_VALUE;
System.out.println(d + " " + asDouble(d));
System.out.println(l + " " + asDouble(l)); // Compile error.
}
}
Of course, there are limitations to this approach - it won't uncover problems in existing code. But strategic use of it could provide some safety from loss of precision in important areas of your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With