zoukankan      html  css  js  c++  java
  • No.5 表达式中的陷阱

    1. 关于字符串的陷阱

    • JVM对字符串的处理
      • String java = new String("Java"); 创建了几个对象?
        • 2个。“Java”直接量对应的字符串对象;new String()构造器返回的字符串对象
        • java.intern() 可以字符串池中的直接量对象。
      • 字符串及基本类型的包装类,Java允许通过直接量的方式来创建对应的Java对象;除此之外,简单的算术表达式、连接计算(编译时可以确定具体值)也可以直接创建对应的Java对象
      • 字符串直接量,JVM会使用一个字符串池保存,第一次使用该直接量时,会将其放在字符串池进行缓存(缓存的意思就是以后再用的话,就直接从池中取,而不会新建啦),一般情况下不会对缓存池中的字符串进行垃圾回收
      • 只要是编译时就可以确定其具体值的字符串直接量,JVM会在编译时确定其具体值,并让它指向字符串池中对应的字符串,否则,就不能利用JVM的字符串池了
        • 何为编译时确定具体值?
          • 没有方法调用;没有变量引用
          • 当然,“宏替换”的变量除外
      • String str = "hello" + “world”; 创建了几个字符串对象
        • 1个。因为在编译时就可以确定其计算后的值,因此就直接把计算后的值放到池中就好了,其它的也没有必要啊
      • 在使用字符串、基本类型包装类的对象实例时,尽量通过  直接量 来创建实例。可以少创建一个对象,提升性能。
    • String是典型的不可变类。可变字符串推荐使用StringBuilder
    • 字符串比较
      • 底层是字符串数组
      • 两个字符串左对齐,依次比较二者的每个字符

    2. 表达式类型的陷阱

      表达式也是具有制定的数据类型的

    • 表达式类型的自动提升
      • 当算事表达式中含有多个基本数据类型时,整个表达式的数据类型会自动提升,提升到与表达式中最高等级操作数同样的类型。
      • 操作数的等级排列如图示

    • 复合赋值运算符的陷阱(+=、-=、/=、...)
      • E1 op= E2 等价于  E1  = (E1的类型)(E1 op E2)
      • eg:a += 5  等价于 a = (a的类型)(a + 5)
      • 陷阱:它潜在的隐式转换  可能 导致计算结果的   高位“截断”(结果强制转换发生溢出时)

    3. 输入法导致的陷阱

    • 代码中 含有   全角空格。。。提示:“非法字符:12288”
    • java程序中不能包含  全角字符  ,但  字符串中和注释中可以

    4注释的字符必须合法

    • 大部分情况,编译器会直接忽略掉注释部分,例外:要求注释部分为合法字符,Java允许直接使用uXXXX形式来表示字符,其中X必须为0~F间的字符
    • // unit55.4Hello.javaInvalid unicode

    5. 转义字符: Java对待转义字符的处理:直接替换成对应的字符

    • 慎用Unicode转义形式
      • System.out.println("abcu000a".length());String literal is not properly closed by a double-quote  因为u000a表示一个换行符
    • 中止行注释的
      • // u000a代表一个换行符 ,会造成错误:代表一个换行符 cannot be resolved to a type

    6. 泛型可能引起的错误

    • 如果使用带泛型声明的类时没有传入类型实参,那么这个类型参数默认是声明该参数时指定的第一个上限类型,这个类型参数也被称为raw type(原始类型)
    • 原始类型带来的擦除
      • 当把一个具有泛型信息的对象赋给另一个没有泛型信息的变量时,所有尖括号之间的类型信息都将被丢弃。例:讲一个List<String>类型的对象转为List,则该List对集合元素的类型检查变成了类型变量的上限(即 Object)
      •  1 package test1;
         2 
         3 import java.util.ArrayList;
         4 import java.util.List;
         5 
         6 public class Test<T extends Number> {
         7     T size;
         8     public Test(){}
         9     public Test(T size){
        10         this.size = size;
        11     }
        12     public T getSize() {
        13         return size;
        14     }
        15     public void setSize(T size) {
        16         this.size = size;
        17     }
        18     public List<String> getStrings(){
        19         List<String> list = new ArrayList<>();
        20         for (int i = 0; i < 3; i++) {
        21             list.add(new Test<Integer>(10 * i).toString());
        22         }
        23         return list;
        24     }
        25     
        26     public static void main(String[] args) {
        27         Test<Integer> test1 = new Test<>(6);
        28         for (String string : test1.getStrings()) {
        29             System.out.println(string);
        30         }
        31         
        32         
        33         Test test2 = test1;
        34         //test2.getStrings()方法中List<String>的String也会丢失;因此是所有尖括号中的泛型信息都会丢失
        35         for (String string : test2.getStrings()) {//Type mismatch: cannot convert from element type Object to String
        36             System.out.println(string);
        37         }
        38         
        39     }
        40 }

    7. 正则

    • split()方法中传入的是正则,正则中“.”匹配任何字符,故需要对其转义 str.split("\.");
    • ps:""  <mine>
      • 字符串中、正则中的“”都表示各自的转义,要用真正的斜线“”时,需要用"\"表示。两者均是如此
      • Java中又是用字符串来表示正则,故表示正则中的斜线时,需要用“\\”前两个斜线表示正则中的第一个斜线,后两个代表第二个
      • (\)(\)即是()(),因为字符串中表示斜线,需要用\。另,各自的转义符是各自的,正则不能利用字符串的转义符,正则的转义符在字符串看来就是一个“”,两者互不干扰,只是可以互相表示
      • ——> 方法:先写出来普通的正则表达式,在Java的字符串中用“\”将正则表达式的斜杠一一表示出来就可以了,有几个就替换几次
        • 例:正则:d  Java中字符串“\d”,即“(\)d”的意思;正则:\  字符串“\\”,即“(\)(\)”;正则:\d,字符串“\\\d”,即“(\)(\)(\)d”

     8. 多线程

    • start()方法启动线程,而不是run()方法
    • 静态同步方法的同步监视器为  当前类本身(类对象)
    • 分析一个程序不能仅仅停留在静态的代码上,而是应该从程序执行过程来把握程序的运行细节
    PS:不足之处,欢迎指正、交流
  • 相关阅读:
    阶段3 3.SpringMVC·_03.SpringMVC常用注解_1 RequestParam注解
    阶段3 3.SpringMVC·_02.参数绑定及自定义类型转换_7 获取Servlet原生的API
    函数传参
    利用 操作符特性 代替if判断语句
    for(;;)和 while(1) 有什么区别吗?for()和while()的使用情景。
    一个简单的mfc单页界面文件读写程序(MFC 程序入口和执行流程)
    ARM异常---一个DataAbort的触发过程:
    C语言,单链表操作(增删改查)(version 0.1)
    Cpu实验
    H-JATG:NAND_FLASH的参数设置
  • 原文地址:https://www.cnblogs.com/fang--/p/6266472.html
Copyright © 2011-2022 走看看