摘《JAVA核心技术卷1》

  1. u是转义序列,一定要当心注释中的 u。注释
    // u000A is a newline
    会产生一个语法错误, 因为读程序时 u000A会替换为一个换行符类似地,下面这个注释
    // Look inside c:users
    也会产生一个语法错误, 因为 u 后面应该跟着 4 个十六进制数

  2. 尽管 $ 是一个合法的 Java 字符, 但不要在你自己的代码中使用这个字符。它只用
    在 Java 编译器或其他工具生成的名字中。

  3. 可以在一行中声明多个变量:
    int i , j // both are integers
    不过,不提倡使用这种风格。逐一声明每一个变量可以提高程序的可读性。

  4. 需要注意, 整数除0将会产生一个算术异常 (java.lang.ArithmeticException: / by zero)
    而浮点数除0除将会得到无穷大(Infinity)NaN 结果。

  5. 在默认情况下, 虚拟机设计者允许对中间计算结果采用扩展的精度(double64,但寄存器80位)。
    但是, 对于使用 strictfp 关键字标记的方法必须使用严格的浮点计算来生成可再生的结
    例如,可以把 main 方法标记为
    public static strictfp void main(String[] args)
    于是,在 main 方法中的所有指令都将使用严格的浮点计算。如果将一个类标记为
    strictfp, 这个类中的所有方法都要使用严格的浮点计算。

  6. 下列返回类型都是dobule

    Math.sqrt(4) //2.0   
    Double Math.pow() 
    
  7. 虚线表示转换时会损失精度,int转float会损失精度,精度和大小是不同的概念

  8. 位运算符
    处理整型类型时,可以直接对组成整型数值的各个位完成操作。这意味着可以使用掩码
    技术得到整数中的各个位。位运算符包括:
    &("and") |("or") ^("xor") ~("not")
    应用在布尔值上时, & 和丨运算符也会得到一个布尔值。不过 & 和丨运算符不采用“ 短路” 方式来求值, 而是两个操作数都需要计算。
    >><<运算符将位模式左移或右移。需要建立位模式来完成位掩码时, 这两个运算符会很方便:
    int fourthBitFromRight = (n & (1« 3)) » 3;
    最后 >>> 运算符会用 0 填充高位,这与>>不同,它会用符号位填充高位。不存在<<<运算符。
    警告: 移位运算符的右操作数要完成模 32 的运算(除非左操作数是 long 类型, 在这种情
    况下需要对右操作數模 64 )。
    例如, 1 << 35 的值等同于 1 << 3 或 8。

  9. 如果虚拟机始终将相同的字符串共享, 就可以使用=运算符检测是否相等。但实际上
    只有字符串常量是共享的,而 + 或 substring 等操作产生的结果并不是共享的。

    String greeting = "Hello"; //initialize greeting to a string
    if (greeting == "Hello") .
    // true
    if (greeting.substring(0, 3) == "Hel") . . .
    // false
    
    String i = "H";
    String j = "Hi";
    System.out.println(i+"i" ==j);//false
    
    String i = "H"+"i";
    String j = "Hi";
    System.out.println(i ==j);//true
    
  10. 在 Java 中, 允许数组长度为 0。在编写一个结果为数组的方法时, 如果碰巧结果为空,则这种语法形式就显得非常有用。此时可以创建一个长度为 0 的数组:
    new elementType[0]
    注意, 数组长度为 0 与 null 不同。

  11. 类的成员变量中有对象类型,那么可能会破坏封装性:越过类中方法,直接调用对象方法改变对象状态。如果需要返回一个可变对象的引用, 应该首先对它进行克隆(clone )。对象 clone 是
    指存放在另一个位置上的对象副本。 下面是修改后的代码:

    class Employee
    {
    public Date getHireDayO
    {
    return (Date) hireDay.cloneO; // Ok
    }
    

    凭经验可知, 如果需要返回一个可变数据域的拷贝,就应该使用 clone。

  12. final 修饰符大都应用于基本 (primitive ) 类型域,或不可变(immutable) 类的域(如果类
    中的每个方法都不会改变其对象, 这种类就是不可变的类。例如,String类就是一个不可变
    的类)。
    对于可变的类, 使用 final 修饰符可能会对读者造成混乱。例如,
    private final StringBuiIcier evaluations;
    在 Employee 构造器中会初始化为
    evaluations = new StringBuilder();
    final 关键字只是表示存储在 evaluations 变量中的对象引用不会再指示其他 StringBuilder
    对象。不过这个对象可以更改:

    public void giveGoldStarO
    {
    evaluations.append(LocalDate.now() + ": Gold star!
    ");
    }
    
  13. 数组继承了 object 类的 toString 方法,数组类型将按照旧的格式打印。例如:

    int[] luckyNumbers = { 2, 3, 5, 7 S llf 13 } ;
    String s = "" + luckyNumbers;
    生成字符串“ [I@la46e30”
    

    (前缀 [I 表明是一个整型数组)。修正的方式是调用静态方法 Arrays.toString。代码:

    String s = Arrays.toString(luckyNumbers);
    将生成字符串“ [2,3,5,7,11,13]”。
    

    要想打印多维数组(即,数组的数组)则需要调用 Arrays.deepToString 方法。

  14. 分配数组列表:
    new ArrayListo(100) // capacity is 100
    它与为新数组分配空间有所不同:
    new Employee[100] // size is 100
    数组列表的容量与数组的大小有一个非常重要的区别。如果为数组分配 100 个元素的存储空间,数组就有 100 个空位置可以使用。 而容量为 100 个元素的数组列表只是拥有保存 100 个元素的潜力 ( 实际上, 重新分配空间的话,将会超过丨00 ), 但是在最初,
    甚至完成初始化构造之后,数组列表根本就不含有任何元素。

    List list = new ArrayList<>(10);
    System.out.println(list.size());//0
    int[] i = new int[10];
    System.out.println(i.length);//10
    
  15. @SuppressWarnings("unchecked") 标注来标记
    这个变量能够接受类型转换/压制警告信息

  16. == 运算符也可以应用于对象包装器对象, 只不过检测的是对象是否指向同一个存储区域, 因此,下面的比较通常不会成立:

    Integer a = 1000;
    Integer b = 1000;
    if (a = b) . . .
    

    然而,Java 实现却有可能( may) 让它成立。自动装箱规范要求 boolean、byte、char 127, 介于 -128 ~ 127 之间的 short 和
    int 被包装到固定的对象中。

  17. 能够分析类能力的程序称为反射(reflective )。
    有时候,变量的取值只在一个有限的集合内。对这种情况, 可以自定义枚举类型。
    鉴于历史原因,getName 方法在应用于数组类型的时候会返回一个很奇怪的名字:
    Double[ ] class.getName( ) 返回[Ljava.lang.Double,
    int[ ].class.getName( ) 返回[I

  18. 在 Java 语言中, 给出了 3 种处理系统错误的机制:
    • 抛出一个异常
    • 日志
    • 使用断言
    什么时候应该选择使用断言呢? 请记住下面几点:
    • 断言失败是致命的、 不可恢复的错误。
    • 断言检查只用于开发和测阶段(这种做法有时候被戏称为“ 在靠近海岸时穿上救生衣,
    但在海中央时就把救生衣抛掉吧”)。
    因此,不应该使用断言向程序的其他部分通告发生了可恢复性的错误,或者,不应该作为程序向用户通告问题的手段。断言只应该用于在测试阶段确定程序内部的错误位置。

  19. 泛型相关在 Java 库中, 使用变量 E 表示集合的元素类型, K 和 V 分别表示表的关键字与值的类型。T ( 需要时还可以用临近的字母 U 和 S) 表示“ 任意类型”。
    有时,类或方法需要对类型变量加以约束。怎么才能确信 T 所属的类有 compareTo 方法呢?
    解决这个问题的方案是将 T 限制为实现了 Comparable 接口(只含一个方法 compareTo 的
    标准接口)的类。可以通过对类型变量 T 设置限定(bound) 实现这一点:
    public static <T extends Comparable> T min(T[] a) . . .
    一个类型变量或通配符可以有多个限定, 例如:
    T extends Comparable & Serializable

  20. 队列通常有两种实现方式: 一种是使用循环数组;另一种是使用链表

  21. 编译器简单地将“ foreach” 循环翻译为带有迭代器的循环。it.hasNext()

  22. 如果 a.equals(b) 为 true, a 与 b 必须具有相同的散列码。

  23. 双端队列java.util.Deque:

    • void addFirst(E element )
    • void addLast(E element )
    • boolean offerFirst(E element )
    • boolean offerLast(E element )
    

    将给定的对象添加到双端队列的头部或尾部。如果队列满了,前面两个方法将拋出一个 IllegalStateException,而后面两个方法返回 false。

    • E removeFirst( )
    • E removeLast( )
    • E pollFirstO
    • E pollLastO
    

    如果队列不空,删除并返回队列头部的元素。如果队列为空,前面两个方法将拋出一
    个 NoSuchElementException, 而后面两个方法返回 null。

    • E getFirstO
    • E getLastO
    • E peekFirstO
    • E peekLast( )
    

    如果队列非空,返回队列头部的元素, 但不删除。如果队列空,前面两个方法将拋出
    一个 NoSuchElementException, 而后面两个方法返回 null。

  24. Arrays 类的静态方法 asList 将返回一个包装了普通 Java 数组的 List 包装器。这个方法可
    以将数组传递给一个期望得到列表或集合参数的方法。例如:

    Card[] cardOeck = new Card [52];
    List<Card> cardList = Arrays.asList(cardDeck):
    

    返回的对象不是 ArrayList。它是一个视图对象, 带有访问底层数组的 get 和 set 方
    法。改变数组大小的所有方法(例如,与迭代器相关的 add 和 remove 方法)都会抛出一个
    Unsupported OperationException 异常。

  25. 守护线程的唯一用途是为其他线程提供服务。

  26. accounts[to] += amount;
    于这不是原子操作。该指令可能被处理如下:
    1 ) 将 accounts[to] 加载到寄存器。
    2 ) 增 加 amount。
    3 ) 将结果写回 accounts[to]。

  27. 假设对共享变量除了赋值之外并不完成其他操作,那么可以将这些共享变量声明为
    volatileo

  28. 使用ThreadLocal线程安全化SimpleDateFormat

    public static final ThreadLocal<SimpleDateFormat> dateFormat =
    ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
    

    要访问具体的格式化方法,可以调用:
    String dateStamp = dateFormat.get().format(new DateO);

  29. 执行器(Executor) 类有许多静态工厂方法用来构建线程池,方法描述:

    • newCachedThreadPool: 必要时创建新线程;空闲线程会被保留 60 秒
    • newFixedThreadPool: 该池包含固定数量的线程;空闲线程会一直被保留
    • newSingleThreadExecutor:只有一个线程的 “ 池”, 该线程顺序执行每一个提交的任务(类似于Swing 事件分配线程)
    • newScheduledThreadPool: 用于预定执行而构建的固定线程池, 替代 java.util.Timer
    • newSingleThreadScheduledExecutor: 用于预定执行而构建的单线程 “ 池”
  30. 类之间的关系,类图

原文地址:https://www.cnblogs.com/myzoneliver/p/8390870.html