zoukankan      html  css  js  c++  java
  • 摘《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. 类之间的关系,类图

  • 相关阅读:
    Linux C多线程实现生产者消费者
    数据库视图创建学习
    jsp生成好看的验证码
    每日英语
    ES6学习笔记(一)——let和const
    dataTables的导出Excel功能
    jquery生成二维码图片
    angular2表单初体验
    echarts系列之动态加载数据
    js刷新页面方法
  • 原文地址:https://www.cnblogs.com/myzoneliver/p/8390870.html
Copyright © 2011-2022 走看看