- **Java**
(*http://www.velocityreviews.com/forums/f30-java.html*)

- - **Java multiplication of numbers and**
(*http://www.velocityreviews.com/forums/t625920-java-multiplication-of-numbers-and.html*)

Java multiplication of numbers andI have written my own Arithmetic class to do multiplication of
subclasses of Number and char, etc. But I am not sure how to make multiply() invoke mult() of the right signature. Would I have to go so far as to use Java reflection method such as getConstuctor() in multiply()? Or is there a simpler way? My current code has the following compilation error in the body of multiply(): The method mult(Integer, Integer) in the type Arithmetic is not applicable for the arguments (Object, Object) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public class Arithmetic { public static Integer mult(Integer i, Integer j) { return i * j; } public static Double mult(Double i, Double j) { return i * j; } public static int mult(char i, char j) { return ((int) i * (int) j); } // ... mult() on other data types public static Object multiply(Object i, Object j) { return mult(i, j); } public static void main(String[] args) { System.out.println("3 * 4 = " + Arithmetic.mult((Integer) 3, (Integer) 4)); System.out.println(Arithmetic.multiply(new Integer(1), new Integer(3))); } } |

Re: Java multiplication of numbers andleung.january@gmail.com wrote:
> I have written my own Arithmetic class to do multiplication of > subclasses of Number and char, etc. But I am not sure how to make > public class Arithmetic { > public static Integer mult(Integer i, Integer j) { > return i * j; > } You can't do this. static methods don't participate in polymorphism. And since Integer, Double, etc. are final, you can't extend them. You could make your own classes, although that will be a fair amount of work. And the result would be pretty dubious, the need to box and unbox kills performance. And with char and other primitives there is no hope. They simply do not behave polymorphically, ever, in Java. Here's the closest I could come up with. You could use java.lang.Number instead of MyNumber, but the code will be longer because you have to implement several abstract methods. interface MyNumber<T extends MyNumber> { T mult( T m); } class MyInteger implements MyNumber<MyInteger>{ private int i; MyInteger(int i) { this.i = i; } @Override public MyInteger mult( MyInteger m ) { return new MyInteger(i * m.i); } @Override public String toString() { return Integer.toString(i); } } class MyDouble implements MyNumber<MyDouble> { private double d; MyDouble( double d ) { this.d = d; } @Override public MyDouble mult( MyDouble m ) { return new MyDouble(d * m.d ); } @Override public String toString() { return Double.toString( d ); } } class Arithmetic { public static MyNumber multiply(MyNumber i, MyNumber j) { return i.mult(j); } public static void main(String[] args) { MyNumber k = new MyInteger( 3 ); MyNumber n = new MyInteger( 4 ); MyNumber f = new MyDouble( 2.4456 ); MyNumber g = new MyDouble( 3.14159 ); System.out.println( multiply( k, n ) ); System.out.println( multiply( f, g ) ); } } |

Re: Java multiplication of numbers andleung.january@gmail.com wrote:
> public static Object multiply(Object i, Object j) { > return mult(i, j); > } This is not doing what you think it does (indeed, it causes an error based on the rest of your code). Java has no runtime overloaded method dispatch [1]. The compiler is determining which method to call (modulo virtual effects) based on the /static/ types of the method. So, in short, the compiler is looking for a relevant method mult method that takes as its parameters two Objects or supertypes thereof (and Objects have no supertype). Longer answer, citing from the JLS: Method invocations are covered in §15.12. The process of determining the method at compile-time is in three steps. In the first step, it selects the class to look for the method in. To save you the effort of decoding the spec, it selects Arithmetic as the class. In the second step, it first selects potentially applicable methods (their terminology). Once again, simplifying, it finds the mult methods. It then tries to find the one that should be invoked. The relevant stuff happens in §15.12.2.2 (.3 and .4 are two more phases, but if one ignores auto{un}boxing and variable-arity methods, those don't get applied). Quoting: "Let m be a potentially applicable method (§15.12.2.1), let e_1, ..., e_n be the actual argument expressions of the method invocation and let A_i be the type of e_i, 1 <= i <= n.... [L]et S_1 ... S_n be the types of the formal parameters of m. "The method m is applicable by subtyping if and only if both of the following conditions hold: * "For 1 <= i <= n, either: o "A_i is a subtype (§4.10) of S_i (A_i <: S_i) or o "A_i is convertible to some type C_i by unchecked conversion (§5.1.9), and C_i <: S_i. " Applying this to your case, the A_1 = java.lang.Object, and A_2 = java.lang.Object. The S_1 and S_2 are either both java.lang.Integer, or java.lang.Double, or char. Obviously, an Object is not an Integer nor is it a Double or char, so none of the methods apply. §15.12.2 then proceeds to start delving into more complex matters inapplicable here, especially the process of resolving generic types. This is an interesting discussion, but an off-topic one nonetheless for the problem at hand. However, there is one last useful tidbit of matter, and that emanates from §15.12.2.12: "The most applicable method is chosen at compile time; its descriptor determines what method is actually executed at run time." Paraphrasing, the compiler is the one who decides which method to call, not the runtime engine. All that happens at runtime is that the right overridden method is called (§15.12.4 if you're feeling adventuresome). If you want to be able to dynamically select methods, the only non-reflection mechanisms to do so rely on either overriding polymorphic methods, which static methods are not, or manual switch-like constructs. The structure of Integer/Double/etc. are such that the first approach is likely to present problems. Your other option, of course, is to use reflection. [1] If you really want to split hairs, I believe the JVM's invokedynamic instruction has functionality which could select an overloaded method based on runtime-determined types. However, invokedynamic has no correlating Java equivalent, and can only be emulated through reflection. -- Beware of bugs in the above code; I have only proved it correct, not tried it. -- Donald E. Knuth |

All times are GMT. The time now is 07:11 PM. |

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.

SEO by vBSEO ©2010, Crawlability, Inc.