• java解惑--摘要


    (1)下面是一个试图解决上述问题的程序,它会打印出什么呢?
    public class Change{
    public static void main(String args[]){
    System.out.println(2.00 - 1.10);
    }
    }

    答案:0.8999999999999999

    原因:

    在于1.1 这个数字不能被精确表示成为一个double,因此它被表示成为最
    接近它的double 值。更一般地说,问题在于并不是所有的小数都可以用二进制浮点数来精确表示的

    解决方法:解决该问题的另一种方式是使用执行精确小数运算的BigDecimal。它还可以通

    过JDBC 与SQL DECIMAL 类型进行互操作。这里要告诫你一点: 一定要用
    BigDecimal(String)构造器,而千万不要用BigDecimal(double)。后一个构造
    器将用它的参数的“精确”值来创建一个实例:new BigDecimal(.1)将返回一个
    表示0.100000000000000055511151231257827021181583404541015625 的
    BigDecimal。

    通过正确使用BigDecimal:

    import java.math.BigDecimal;
    public class Change1{
    public static void main(String args[]){
    System.out.println(new BigDecimal("2.00").
    subtract(new BigDecimal("1.10")));
    }
    }

    总之, 在需要精确答案的地方,要避免使用float 和double;对于货币计算,
    要使用int、long 或BigDecimal

    (2)长整除

    public static void main(String args[]){
      
            final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
            final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
            System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY);
            }

    看起来程序打印的必定是1000。
    遗憾的是,它打印的是5

    原因:

    尽管计算的结果适合放
    入long 中,并且其空间还有富余,但是这个结果并不适合放入int 中。这个计
    算完全是以int 运算来执行的,并且只有在运算完成之后,其结果才被提升到
    long,而此时已经太迟了:计算已经溢出了

    下面的程序将打印出我们所期望的
    1000:

    public class LongDivision{
    public static void main(String args[ ]){
    final long MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000;
    final long MILLIS_PER_DAY = 24L * 60 * 60 * 1000;
    System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY);
    }

    结论:此场景在项目中用到的很多,请注意

    (3)x = x + i;与x += i;

    short x = 0;
    int i = 123456;
    x += i; // 包含了一个隐藏的转型!
    x = x + i; // 不要编译——“可能会丢掉精度”
    

      

    public static void main(String args[]){
    
    Object x = "Buy ";
    String i = "Effective Java!";
    x = x + i; //ok,因为 x + i 是String 类型的,而String 类型又是与Object赋值兼容的
    x += i; //译不通过,因为左侧是一个Object 引用类型,而右侧是一个String类型:
    
    }
    结论:

    要想用 += 操作符来执行字符串连接操作,
    你就必须将左侧的变量声明为String 类型。

    如果在+=操作符左侧的操作数是String
    类型的,那么它允许右侧的操作数是任意类型,在这种情况下,该操作符执行的
    是字符串连接操作。简单赋值操作符(=)允许其左侧的是对象引用类型,这就
    显得要宽松许多了:你可以使用它们来表示任何你想要表示的内容,只要表达式
    的右侧与左侧的变量是赋值兼容的即可。

    
    

     (4)字符

      
            System.out.println('H'+'a');  //输出169
            
            StringBuffer sb = new StringBuffer();
            sb.append('H');
            sb.append('a');
            System.out.println(sb); //输出Ha

    (5)

    public static void main(String[] args) {
    System.out.println(decision());
    }
    static boolean decision() {
    try {
    return true;
    } finally {
    return false;
    }
    }

    它所打印的是
    false。

    分析:

    。一条语句或一个语句块在它抛出了一个异常,或者对某个封闭型
    语句执行了一个break 或continue,或是象这个程序一样在方法中执行了一个
    return 时,将发生意外结束。它们之所以被称为意外结束

    当try 语句块和finally 语句块都意外结束时,在try 语句块中引发意外结束的
    原因将被丢弃,而整个try-finally 语句意外结束的原因将于finally 语句块意
    外结束的原因相同。在这个程序中,在try 语句块中的return 语句所引发的意
    外结束将被丢弃,而try-finally语句意外结束是由finally语句块中的return
    造成的。简单地讲,程序尝试着(try)返回(return)true,但是它最终(finally)
    返回(return)的是false。

     

    (5)您好,再见!

    public class HelloGoodbye {
    public static void main(String[] args) {
    try {
    System.out.println("Hello world");
    System.exit(0);
    } finally {
    System.out.println("Goodbye world");
    }
    }
    }
    它只打印了Hello world

    分析:不论try语句块的执行是正常地还是意外地结束,finally语句块确实都会执行。
    然而在这个程序中,try 语句块根本就没有结束其执行过程。System.exit 方法
    将停止当前线程和所有其他当场死亡的线程。finally 子句的出现并不能给予线
    程继续去执行的特殊权限。

    总之,System.exit 将立即停止所有的程序线程,它并不会使finally 语句块得
    到调用

     
  • 相关阅读:
    在浏览器应用中使用 gRPC
    gRPC 客户端工厂集成
    gRPCurl 测试 gRPC 服务
    links
    Flex布局
    使用 IHttpClientFactory 实现复原 HTTP 请求
    Dex Common
    Dex MVVM
    日志
    配置
  • 原文地址:https://www.cnblogs.com/qqzy168/p/3645357.html
Copyright © 2020-2023  润新知