Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to produce a compilation error on implicit long to double conversion?

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.

like image 723
Sebastien Diot Avatar asked Jun 17 '14 13:06

Sebastien Diot


3 Answers

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).

like image 193
Sergey Kalinichenko Avatar answered Oct 31 '22 13:10

Sergey Kalinichenko


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.

like image 31
Joop Eggen Avatar answered Oct 31 '22 13:10

Joop Eggen


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.

like image 1
Alex Avatar answered Oct 31 '22 14:10

Alex