栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

2021-10-23

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021-10-23

每日一题
  • JAVA基础
    • String类、类型转换和BigDecimal
    • 类的加载顺序题

JAVA基础 String类、类型转换和BigDecimal
  1. 请问:String a = "12" + "34" + new String("12") + "1234" ;创建了几个字符串对象?请试着从原理的层次分析一下为什么;
答: 创建了5个对象:

   - "1234"
   - "12"
   - "1234121234"
   - new String()
   - new StringBuilder().append("12").append("34").append("12").append("1234").toString()

   > 分析:字符串常量在编译器会进行优化,`"12" + "34"`被优化为 `"1234"`,在字符串常量池新建字
   > 符串对象`"1234"`;`new String("12")`这里面的`"12"`在字符串常量池不存在,所以会在字符串
   > 常量池新建字符串对象`"12"`;后面的 `"1234"`由于在常量池已经创建好了,所以不会再创建。
   > 那么加上`new String()`创建的对象、`StringBuilder`拼接产生的新字符串
   > 对象`"1234121234"`以及StringBuilder本身toString方法产生的对象,
   > 理想情况下会产生共5个字符串对象。

   > ```java
   > // 扩展:来看看这个例子:
   > String a = "123";
   > String b = new String("123");
   > String c = "1" + "23";
   > String d = "1";
   > String e = d + "23";
   > System.out.println(System.identityHashCode(a)); // 打印字符串的原始内存地址的hash值  460141958
   > System.out.println(System.identityHashCode(b)); // 1163157884
   > System.out.println(System.identityHashCode(c)); // 460141958
   > System.out.println(System.identityHashCode(e)); // 1956725890
   > // 可以看到,a和 c的内存地址一致,因为都是在字符串常量池里面,引用的是同一个对象
   > // b 新建了一个字符串对象 new String()
   > // e 是拼接而成,也就是 new StringBuilder().toString(),toString()里面还是新建了一个字符串new String()
   > ```

难疑点:字符串常量? 字符串常量池?为什么会调用StringBuilder`拼接?

  1. short s1 = 1; s1 = s1 + 1;会正确运行吗?short s1 = 1; s1 += 1;会正确运行吗?请问为什么会出现这样的结果?
    答:. s1 = s1 + 1;会报错,因为short、byte、char等类型在做运算的时候会提升类型到int类型,int类型运算完成赋值给short类型会发生类型转换错误,可以强制进行转换:s1 = (short) (s1 + 1);s1 += 1;可以正常运行,因为+=` 操作符会自动进行转换操作,也就是使用 short(1) 进行运算
    难疑点:数据类型的类型转换?
  2. double a = 1d - 0.9d; double b = 0.9d - 0.8d;请问a == b 成立吗?为什么?在Java中涉及到这样的精确计算应该怎么办?
    答:a == b 成立,结果都是0.09999999999999998,Java在进行 - 和 / 运算的时候,无法精确计算,可以使用 BigDecimal 类型进行计算。需要注意的是 BigDecimal.valueOf(0).equals(BigDecimal.valueOf(0.0)) 返回的结果是false,因为它的equals方法比较了小数位,所以不相等,可以使用 compareTo方法比较。
类的加载顺序题
  1. (必做)有下面的一个类,请问最后main方法输出是什么?请试着分析打印输出的过程,写出自己的理解。
 ```java
   public class Book {
       static Book book = new Book();
       static int amount = 112;
       static {
           System.out.println("书的静态代码块");
           System.out.println("amount=" + amount);
       }
       int price = 110;
   
       {
           System.out.println("书的普通代码块");
       }
   
       Book() {
           System.out.println("书的构造方法");
           System.out.println("price=" + price + ",amount=" + amount);
       }
   
       public static void staticFunction() {
           System.out.println("书的静态方法");
       }
   
       public static void main(String[] args) {
           staticFunction();
       }
   
   }
   答案:

   运行的结果为:

   > 书的普通代码块
   >
   > 书的构造方法
   >
   > price=110,amount=0
   >
   > 书的静态代码块
   >
   > amount=112
   >
   > 书的静态方法

分析:

   > 1. 运行main方法,会先发生 Book 类的加载,类加载的过程是:`加载->验证->准备->解析->初始化->使用->卸载`,在执行初始化这个阶段的时候,会对类所有的静态变量进行初始化,也就是`book = null`,`amount=0`。注意:假如使用final修饰静态变量,它是不会初始化的,直接赋值,因为final修饰的变量不可改变;
   >
   > 2. 第二步是对静态变量赋值,先赋值`book = new Book();`这个地方new 了一个Book,new Book()需要**类加载**,然后再进行**对象实例化**,但是类加载已经进行过了,那么这次就直接实例化对象了。
   >
   > 3. 实例化Book对象,需要先对Book的成员变量赋值` int price = 110`,然后执行代码块 `{ System.out.println("书的普通代码块"); }`,所以我们看到控制台先打印了这句话,接着执行**构造方法**,打印输出 `书的构造方法`,打印输出`price=110,amount=0`,`price=110`很好理解,就是刚才在实例化对象的时候成员变量赋值,那么`amount=0`呢?这就得联系到刚才初始化类的时候我们给类的静态变量初始化,amount被初始化为0,所以打印了`amount=0`。
   >
   > 4. 再往下继续给类的静态变量赋值,`amount = 112;`,赋值完所有的静态变量后开始执行类的静态方法块,
   >
   >    `static {
   >            System.out.println("书的静态代码块");
   >            System.out.println("amount=" + amount);
   >        }`
   >
   >    于是,打印输出了 `书的静态代码块`和 `amount=112`。
   >
   > 5. 类加载结束之后,开始执行main方法里面的代码,打印 `书的静态方法` 这句话。
   >
   > 以上就是整个类加载到执行main方法的全部过程,只有静下心来认真思考,并且对类加载的知识有一定的掌握,才能分析的出来。
![类的加载图](https://img-blog.csdnimg.cn/180605855b53406c86645e9adf821b52.jpg?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5bCR5bm06Zi_5Y2OLg==,size_20,color_FFFFFF,t_70,g_se,x_16)




### 三级目录
### 三级目录

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/349557.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号