Double值比较真相揭秘

发布时间:2026/8/4 3:02:17
Double值比较真相揭秘 以下是各程序清单的执行结果及核心要点解析Listing 1: DoubleDemoclass DoubleDemo { public static void main(String args[]) { Double d1 Double.valueOf(3.14159); Double d2 Double.valueOf(314159E-5); System.out.println(d1 d2 - d1.equals(d2)); } }执行结果3.14159 3.14159 - true解析Double.valueOf(3.14159)和Double.valueOf(314159E-5)都创建了表示相同浮点数值的Double对象。Double.equals()方法比较的是包装对象内部的基本double值而非对象引用。由于两个值在浮点数精度内相等因此返回true。Listing 2: InfNaNclass InfNaN { public static void main(String args[]) { Double d1 Double.valueOf(1/0.); Double d2 Double.valueOf(0/0.); System.out.println(d1 : d1.isInfinite() , d1.isNaN()); System.out.println(d2 : d2.isInfinite() , d2.isNaN()); } }执行结果Infinity: true, false NaN: false, true解析1/0.在浮点数运算中结果为无穷大 (Infinity)isInfinite()返回true。0/0.在浮点数运算中结果为“非数字” (NaN)isNaN()返回true。Listing 3: ParseDemoimport java.io.*; class ParseDemo { public static void main(String args[]) throws IOException { BufferedReader br new BufferedReader(new InputStreamReader(System.in)); String str; int i; int sum0; System.out.println(Enter numbers, 0 to quit.); do { str br.readLine(); try { i Integer.parseInt(str); } catch(NumberFormatException e) { System.out.println(Invalid format); i 0; } sum i; System.out.println(Current sum is: sum); } while(i ! 0); } }执行结果示例交互Enter numbers, 0 to quit. 5 Current sum is: 5 10 Current sum is: 15 abc Invalid format Current sum is: 15 0 Current sum is: 15解析程序从标准输入读取数字字符串使用Integer.parseInt()进行转换并累加。输入非数字字符串会抛出NumberFormatException被捕获后提示并计为0。输入0时循环终止。Listing 4: StringConversionsclass StringConversions { public static void main(String args[]) { int num 19648; System.out.println(num in binary: Integer.toBinaryString(num)); System.out.println(num in octal: Integer.toOctalString(num)); System.out.println(num in hexadecimal: Integer.toHexString(num)); } }执行结果19648 in binary: 100110011000000 19648 in octal: 46300 19648 in hexadecimal: 4cc0Listing 5: IsDemoclass IsDemo { public static void main(String args[]) { char a[] {a, b, 5, ?, A, }; for(int i0; ia.length; i) { if(Character.isDigit(a[i])) System.out.println(a[i] is a digit.); if(Character.isLetter(a[i])) System.out.println(a[i] is a letter.); if(Character.isWhitespace(a[i])) System.out.println(a[i] is whitespace.); if(Character.isUpperCase(a[i])) System.out.println(a[i] is uppercase.); if(Character.isLowerCase(a[i])) System.out.println(a[i] is lowercase.); } } }执行结果a is a letter. a is lowercase. b is a letter. b is lowercase. 5 is a digit. A is a letter. A is uppercase. is whitespace.Listing 6: MemoryDemoclass MemoryDemo { public static void main(String args[]) { Runtime r Runtime.getRuntime(); long mem1, mem2; Integer someints[] new Integer[1000]; System.out.println(Total memory is: r.totalMemory()); mem1 r.freeMemory(); System.out.println(Initial free memory: mem1); r.gc(); mem1 r.freeMemory(); System.out.println(Free memory after garbage collection: mem1); for(int i0; i1000; i) someints[i] Integer.valueOf(i); mem2 r.freeMemory(); System.out.println(Free memory after allocation: mem2); System.out.println(Memory used by allocation: (mem1-mem2)); for(int i0; i1000; i) someints[i] null; r.gc(); mem2 r.freeMemory(); System.out.println(Free memory after collecting discarded Integers: mem2); } }执行结果示例具体数值因环境而异Total memory is: 130023424 Initial free memory: 128632160 Free memory after garbage collection: 129378880 Free memory after allocation: 129374152 Memory used by allocation: 4728 Free memory after collecting discarded Integers: 129378880解析展示了Runtime类中totalMemory()、freeMemory()和gc()方法的使用。gc()是建议JVM进行垃圾回收不保证立即执行。分配Integer对象数组会消耗内存将其置为null并调用gc()后内存被回收。Listing 7: ExecDemoclass ExecDemo { public static void main(String args[]) { Runtime r Runtime.getRuntime(); Process p null; try { p r.exec(notepad); } catch (Exception e) { System.out.println(Error executing notepad.); } } }执行结果启动 Windows 记事本程序 (notepad.exe)。程序会立即返回不会等待记事本关闭。Listing 8: ExecDemoFiniclass ExecDemoFini { public static void main(String args[]) { Runtime r Runtime.getRuntime(); Process p null; try { p r.exec(notepad); p.waitFor(); } catch (Exception e) { System.out.println(Error executing notepad.); } System.out.println(Notepad returned p.exitValue()); } }执行结果启动 Windows 记事本并调用p.waitFor()等待其进程终止。关闭记事本后控制台输出其退出码通常为0。Listing 9 20: VerDemoclass VerDemo { public static void main(String args[]) { Runtime.Version ver Runtime.version(); System.out.println(Major version: ver.major()); System.out.println(Minor version: ver.minor()); System.out.println(Security version: ver.security()); } }执行结果示例取决于JDK版本Major version: 17 Minor version: 0Security version: 0Listing 10: PBDemoclass PBDemo { public static void main(String args[]) { try { ProcessBuilder proc new ProcessBuilder(notepad.exe, testfile); proc.start(); } catch (Exception e) { System.out.println(Error executing notepad.); } } }执行结果使用ProcessBuilder启动记事本并尝试打开名为testfile的文件。如果文件不存在记事本会新建一个空白文档。Listing 11: Elapsedclass Elapsed { public static void main(String args[]) { long start, end; System.out.println(Timing a for loop from 0 to 100,000,000); start System.currentTimeMillis(); for(long i0; i 100000000L; i) ; end System.currentTimeMillis(); System.out.println(Elapsed time: (end-start)); } }执行结果示例Timing a for loop from 0 to 100,000,000 Elapsed time: 25解析使用System.currentTimeMillis()测量一个空循环的执行时间。Listing 12: ACDemoclass ACDemo { static byte a[] { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74 }; static byte b[] { 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 }; public static void main(String args[]) { System.out.println(a new String(a)); System.out.println(b new String(b)); System.arraycopy(a, 0, b, 0, a.length); System.out.println(a new String(a)); System.out.println(b new String(b)); System.arraycopy(a, 0, a, 1, a.length - 1); System.arraycopy(b, 1, b, 0, b.length1); System.out.println(a new String(a)); System.out.println(b new String(b)); } }执行结果a ABCDEFGHIJ b MMMMMMMMMM a ABCDEFGHIJ b ABCDEFGHIJ a AABCDEFGHI b BCDEFGHIJJ解析演示System.arraycopy()方法进行数组复制。第一次复制将a的内容完全复制到b。第二次复制a自我复制导致元素右移b自我复制导致元素左移。Listing 13: ShowUserDirclass ShowUserDir { public static void main(String args[]) { System.out.println(System.getProperty(user.dir)); } }执行结果输出当前 Java 进程的工作目录绝对路径。Listing 14 15: CloneDemo 系列这两个清单展示了两种实现克隆的方式。Listing 14使用自定义的cloneTest()方法。Listing 15重写了Object.clone()方法并提升为public。执行结果两者相同x1: 10 20.98 x2: 10 20.98解析实现了Cloneable接口的类才能进行克隆。*克隆创建了原对象的一个副本副本的字段值与原对象相同。Listing 16: RTTIclass X { int a; float b; } class Y extends X { double c; } class RTTI { public static void main(String args[]) { X x new X(); Y y new Y(); Class? clObj; clObj x.getClass(); System.out.println(x is object of type: clObj.getName()); clObj y.getClass(); System.out.println(y is object of type: clObj.getName()); clObj clObj.getSuperclass(); System.out.println(ys superclass is clObj.getName()); } }执行结果x is object of type: X y is object of type: Y ys superclass is X解析演示运行时类型信息RTTI通过getClass()获取对象的Class对象。Class.getName()返回类名getSuperclass()返回父类的Class对象。Listing 17: Anglesclass Angles { public static void main(String args[]) { double theta 120.0; System.out.println(theta degrees is Math.toRadians(theta) radians.); theta 1.312; System.out.println(theta radians is Math.toDegrees(theta) degrees.); } }执行结果120.0 degrees is 2.0943951023931953 radians. 1.312 radians is 75.17206272116401 degrees.Listing 18: ThreadGroupDemo执行结果摘要创建两个线程组Group A 和 Group B每个组包含两个线程。线程启动后打印倒数数字。主线程暂停 Group A 中的线程 4 秒然后恢复。所有线程执行完毕后主线程退出。groupA.list()和groupB.list()会向标准错误输出线程组信息。Listing 19: PkgTestclass PkgTest { public static void main(String args[]) { Package pkgs[] Package.getPackages(); for(int i0; i pkgs.length; i) System.out.println( pkgs[i].getName() pkgs[i].getImplementationTitle() pkgs[i].getImplementationVendor() pkgs[i].getImplementationVersion() ); } }执行结果输出当前类加载器加载的所有包的信息包括包名、实现标题、供应商和版本。输出内容因运行环境和JDK版本而异可能很长。参考来源java中system_Java中System类Soot Java程序分析与优化实战示例jacoco java_使用Jacoco获取 Java 程序的代码执行覆盖率jacoco java_使用Jacoco获取 Java 程序的代码执行覆盖率stopwatch java_利用StopWatch类监控Java代码执行时间并分析性能

相关新闻