[版权声明] 自由转载-非商用-非衍生-保持署名 (CC BY-NC-ND 3.0)
[发表日期] 2015年12月22日 18:00 @欢乐小匠仙
[原文地址] http://leeyee93.cnblogs.com/p/5067451.html
eclipse用 workspace 管理 working set 管理 project 管理 package 管理 class
记住:表达式(运算、甚至一个数)是有返回值的!
高淇Java300集 · 匠仙版笔記
先将编程环境的编码改成 UTF-8, 避免后患无穷
1.学习方式:深入内存结构、分析JDK源码;学习JAVA:企业级服务器端开发 + Android开发;学习编程语言的方法:找准一门语言,精通它。
2. 一代机器语言 - 二代汇编语言 - 三代高级语言(面向过程、面向对象) - 四代SQL(存疑):向着人更加容易使用的方向发展。
3. 做产品的标准:比上一代产品更加容易被人使用、功能更加强大。
4. 机器0101 - 汇编abbr. - 硬件从电子管到晶体管性能提升,计算机开始可以做更多的事,于是需要更多软件,汇编不够了。
5. 面向过程C_FORTRAN_COBOL_PASCAL_ADA;面向对象C++_JAVA_C#
6. JAVA核心优势:跨平台。JVM (Sun针对不同系统提供不同虚拟机、由Sun解决系统差异而不用你操心)
8. JAVA各版本和体系架构:
9. JDK(oracle.com/downloads)
10. 标识符以字母、下划线、美元符开头(甚至汉字)。
11. Unicode中一个字符占两个字节:1B=8bit, 2^8=256; 2B=16bit, 2^16=65536; 汉字大概占两万。
12. 字符集 (ISO8859-1 - BIG5 + GB2312 GBK GB18030 + Unicode)。
13. JAVA数据类型:四类八种基本类型 + 对象引用。
14. byte short int long _ 1 2 4 8 字节 _ -128~127 正负3万 正负21亿 国象棋盘放米;BigInteger类。
15. 进制转换:Integer.to?String(), ?=Binary Octal Hex。
16. 整型常量 (字面量) 默认是int;(初始化) 整型常量不超范围可以自动转型为 byte short char。
17. float double _ 4 8字节。浮点常量 (字面量) 默认是double。
18. float范围比int大,有限范围内表示无限的小数,并不能精确表示所有小数,有舍入误差;使用BigDecimal类精确;避免比较浮点数。
19. char占2字节;转义字符(单引、双引、反斜杠、制表、换行);运算时直接当作整数来运算。
20. 自动类型转换:
21. 自动类型转换:int/long可以转float但可能损失精度,long可以转double但可能损失精度,int转double不会。
22. 强转超出了目标类型的表数范围,就会被截断成为一个完全不同的值。
23. 注意做二元运算符的计算时,自动类型转换可能会导致类型提升的问题。
24. 自动类型转换看容量(容量是表数范围而不是字节数), long是2^63,float是3.4e38 (double是1.7e308)。
25. JDK7新特性:二进制整数0b (用于更方便地操作内存与移位运算,写游戏和权限管理会常用)。
26. JDK7新特性:下划线分隔符 (对长数字进行分段书写, 四位一隔致脱口念出)。
27. 局部变量在使用前必须先声明和初始化。
28. final常量(最终变量)只能被初始化一次;使用 [全大写+下划线] 命名 (Ruby约定高于配置 -小写就是变量 大写就是常量)。
29. 标识zhi4符:见名知意 动名分开 - 变量名、方法名首字母小写和驼峰;类名首字母大写和驼峰。
30. 运算符:
31. 二元运算符类型提升与一元运算符的顺序:
32. 逻辑短路:逻辑&&的第一个是false则不算第二个 逻辑或的第一个是true则不算第二个;移位与或不短路。
33. 逻辑与或只能操作布尔变量,按位与或(位运算符)还可以操作整数;按位与& - 有0则0无0则1;按位异或^ - 同则0;取反~。
34. 注意:int 四个字节,默认二进制32位;取反会改变符号位。
35. 左移一位 (<<1 ) 相当于乘以2,右移一位 ( >>1 ) 相当于除以2;移位运算符后面跟着的操作数是移动的位数。
36. 试题:乘除 2、4、8… 怎么算最快?移位。
37. 优先级:先乘除后加减 表达式里面优先使用小括号来组织。
38. 编程的本质:尽快地将业务逻辑用代码实现!而学javase用记事本还是eclipse其实关系不大,不要在这种问题上用错力。
39. eclipse: Window - Show view - Outline视图用于查看类结构。主要是看方法,尤其是重载。
40. eclipse: 断点:程序在调试模式下运行时会停下来的地方 (双击加消断点,右键debug as)。
41. eclipse: debug视图的4个按钮:运行到下个断点或运行到底F8 停止CTRL+F2 进入方法F5 下一行F6 (F2=Focus Ctrl+1=QuickFix)。
42. eclipse: F11=debug,Ctrl+F11=run;将run改为F10 (其实也不用改,如果不设断点,debug就是run),Hide Toolbar。
43. 控制语句:(顺序结构)、[单双多]选择结构(if好习惯-即使1行都打花括号-否则控制范围只有第一条语句)、循环结构。
44. switch语句专做等值判断,注意break丢失导致case穿透:无视case值而接着执行case里的代码直到碰到break为止。
45. 多行case只写值、不写体,间接地利用case穿透做多个等值判断。
46. JDK7新特性:switch表达式结果可以是字符串 (+int和枚举)。
47. while循环:如果条件满足,则再来一次(先判断后执行,而 do{}while(); 先执行后判断)。
48. eclipse: 修改变量名,为防遗漏要使用右键 - Refactor – Rename。
49. 解题技巧:【删题干】简化分解难题,一块一块实现
50. 解题技巧: for循环打印九九乘法表?首先要保持一个积极的心态,“你肯定会!”,首先你不学循环你会不会?第一反应是我能做,然后再去考虑怎么做的问题。
51. goto的影子:带标签的break和continue (JAVA保留goto关键字但没有功能)。
52. 方法:形参parameter-在方法被调用时用于接收外界输入的数据;实参argument-调用方法时实际传给方法的数据。本质不同:形参的本质是一个名字,不占用内存空间。实参的本质是一个变量,已经占用内存空间。
53. 方法:JAVA中只有值传递-基本数据类型传数据值本身,引用类型传对对象的引用,而不是对象本身。
54. 设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样利于我们后期的扩展。
55. 递归 = 递归头(什么时候不调自己) +递归体(什么时候调自己)。
56. 递归图示与内存精讲:递归两个阶段-递推与回归。
http://www.cnblogs.com/whl2012/p/3608973.html
57. 递归:程序调用自身的编程技巧 (例题:阶乘计算和斐波那契数列)。
58. api:包(所有包) - 类(包下所有的类和接口) - 详(类和接口的详细说明);点 Overview 列出所有的包,二级链接有“包概述”。
59. 包?类似于“文件夹”,解决类之间的重名问题 和 便于管理类(合适的类位于合适的包)。
60. 包名:域名倒着写,再加上模块名,并于内部管理类。
61. eclipse: 习惯完全使用 ctrl+n 新建 项目(注意working_set)、包、类。
62. 以后建类都放在包里,不要使用 default 包; package打包:第一句非注释性语句; com.liyi 和 com.liyi.test 是两个独立的包。
63. JDK中主要的包 (lang是java的核心包,默认导入直接用)。
64. eclipse: 生成项目文档。
65. javadoc - 错误:编码GBK的不可映射字符。javac -encoding utf8 ClassName.java
66. eclipse: 项目右键 - Show in - System Explorer。
67.从键盘输入: new Scanner(System.in); .next(); .nextInt()
68. 面向对象本质 (object oriented:(运行时)通过对象来【组织(封装)数据】和 (设计时)通过类来【组织代码】)
69. 面向过程以【方法(函数)】为单位组织代码 (上千方法,难以合作和扩展,80s软件危机,以C“结构体”为桥梁,过渡到 ...),面向对象以【类】为单位组织代码。
70. 结构体只能将相近的变量丢到一起,在其基础上,将相近的方法也丢到一起;而方法需要反复操作变量数据,干脆把他俩合在一起,就出现了新的概念 - 类。
71. 语言发展史:C - 带类的C(C++) - JAVA(C++-)。
72. 面向过程:这件事需要几个步骤。有枪了,就用枪的思维去思考。面向对象:这件事里有哪些个对象。
73. 物以类聚,分成骑兵、炮兵,但是炮兵开炮也是有步骤。不是有了面向对象就不需要面向过程了。面向对象只是分类,方法的实现还是面向过程。面向对象把握整体,面向过程完成细节。
74. 需要大规模协作的,面向过程搞不掂(你不可能了解每一个步骤细节并方法化),大粒度的面向对象最擅长干这个。
75. “毛”的面向对象:架构优良,扩充容易,便于处理协作问题。
76. OOP本质;对象和类:先有对象后有类,先写类后new对象。
77. 实例变量默认会自动初始化,局部变量不会、必须先手动初始化后使用。
78. 精彩的内存分析(main方法) - 操作对象就是操作他的地址 (引用reference,占4个字节,1位16进制=4位二进制,1位8进制=3位二进制)。
79. JVM为每个已加载的类都维护一个常量池。常量池共享机制:先检查其他常量池里有没有相同的常量,有就共享。
80. 垃圾回收机制:没有被引用的对象叫做垃圾。finalize方法是JAVA提供给程序员用来释放对象或资源的方法,但尽量少用,因为不保证执行 (可以for循环大规模耗尽内存来测试闭包)。
81. 优劣:C++如果多人协作编程,出错的概率极大 (开饭馆的比喻:家庭 vs 餐馆 vs 食堂设想:垃圾回收和手动并用)。
82. 构造方法本质上有返回值(但不需要做任何定义),只用于构造类的对象,通过new来调用 (因为方法需要对象调,此时无对象),默认无参、自定则无。
83. eclipse: Alt+Shift+S = Source;构造方法也是方法,也可以 重载。
84. static内存分析:
85. this又叫隐式参数,我们调用方法时并没有手动传,但jvm自己会把他传进去,this存对象地址值、指向当前对象。因为方法只有一份,如果参数里没有this,又如何知道是哪个对象在调用。
86. 普通方法中,this总是指向调用该方法的对象;构造方法中,this总是指向正要初始化的对象;不能用于static方法;this()调用其他构造器,必须位于第一句。
87. super是另一个隐式参数,指向子类对象内部的父类对象。
88. 面向对象三大特征:继承、封装(隐藏)、多态。
89. OOD:类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建模;OOP:提高代码的复用性(代码重用)。extends=扩展,子类是父类的扩展。
90. 重写和重载没关系,重写是重新实现(覆盖)继承自父类的方法以适应具体情况,重载是一个方法名对应多个形参列表不同的方法实现。
91. eclipse: 设置 Ctrl+单击 查看 jdk类 源码。
92. toString()的源代码:类名getClass().getName() + '@' + 十六进制哈希码Integer.toHexString(hashCode());8位16进制=32位2进制,int型地址。
93. eclipse: 类名Hover~ Ctrl+T = 查看类继承树;快捷键记不住就 右键。
94. super:直接父类 对象 的引用 (JAVA可以继承多个父类,但直接父类只能一个,父类的父类们即间接父类)。
95. eclipse: 选中一段文字(默认当前行),alt+上下方向键,可以上下移动行;空白处 alt+斜线,第一条提示即是 构造器。
96. 构造器内存结构:对象包对象 (wrap结构)。
97. 仅从代码复用角度,组合 完全可以替代 继承。
98. eclipse: 每次保存都会留恢复点,右键 Compare with - Local history,可以选择保存点对比。
99. 逻辑上,is-a关系使用继承,has-a关系使用组合。
100. final关键字修饰 变量、方法、类(String、Math)
101. 封装:encapsulation (capsule是胶囊、太空舱的意思);隐藏对象内部的复杂性,只对外公开简单的接口。
102. 访问控制符及类属性的处理 (成员变量全部私有、常量和static可以公开)。
103. 多态 (调用时只要类里有方法声明就可以通过编译) - 3个必要条件
说一套,做一套(堆内存里实际是什么就是什么),这就是多态。
105. instanceof的使用。
106. 多态的内存分析: this作为隐式参数,永远指向最终对象,但super有层级。
107. 抽象方法:只有方法的声明,没有方法体 (多抽象~)。
抽象方法必须被子类实现,这就是规范。意义在于:将方法的 [设计] 与 [实现] 分离。
108.@Override是注解,被标注的覆盖方法名不能改。注解是jdk5新。
109.接口中只有:常量(public static final)和抽象方法(public abstract)。[设计] 与 [实现] 分离。接口代表规范。
接口里没有什么可以继承的,就是用来被实现的,所以关键字是implements。
常量的使用:MyInterface.MAX_SPEED。
110.有些“能飞的”东西,未必有继承关系。如飞机和石头。对于JAVA,接口补充和改善了“多继承”机制。
111.为什么需要接口?接口抽象类的区别?
112. 接口支持多继承。接口足够简单,不会引入过于的复杂性。但是…
接口常量名歧义:The field TestClass.MAX_VALUE is ambiguous
113.回调的实现:CallBack (或Hook, 钩子函数),所谓“调哪一个、回头再说”,先把调用写死,然后你传哪个我调哪个。也称为 模板方法模式。 [多态的应用]
将你不确定如何实现的方法,或者可能有多种实现 (如“画窗口”,每次画的内容都不一样),交给别人实现。[awt的实现:你写画窗口的方法、它负责注册和调用,内部其实就是一个钩子;如果重写了方法我们没有调用它,却莫名其妙被调(执行)了,要想到这]
你在我的“钩子”上“挂”什么我执行什么 (方法以 父类引用(抽象类或接口,更规范) 做形参,传不同的子类对象;那个方法就是钩子)。
114.interface命名,很多人喜欢首字母加I,如IMyInterface。
*115.冯诺依曼体系结构的本质:加法器+存储器。
*116.关于学习和晕。
117.内部类:在另一个类内部定义的类。
场合:在只为所在外部类提供服务的情况下优先使用。如CPU就是为Computer服务的,别的类也用不着。
好处:别人不能直接访问 CPU,要通过它从属的 外部类(于内部可)直接访问(提供公共方法);CPU可以直接使用Computer的私有属性 (但外部类不能访问内部类的私有属性)。
(内部类提供了更好的封装,只能让外部类直接访问,不允许同一个包中的其他类直接访问)
118.内部类的分类:成员内部类(静态_当一个静态内部类对象存在,并不一定存在对应的外部类对象、非静态)
匿名内部类(适合只需要使用一次的类,定义和调用一起,如键盘监听操作)
new 父类构造器(实参列表) 实现接口() { //匿名内部类类体 }
局部内部类(用得极少,将类定义在方法内部、作用域限于本方法)。
119. 成员内部类编译后的字节码文件名:Outer$Inner.class。
将成员内部类的地位当做类的成员来理解,更容易明白其调用方式。
120. 非静态成员内部类。
创建内部类对象:①Outer o = new Outer(); Outer.Inner i = o.new Inner(); ②Outer.Inner i = new Outer().new Inner();
内部类调用外部类属性如果名字冲突,使用 Outer.this.attribute_name; 构造器里使用this.attribute_name引用内部属性。
非静态内部类里可以直接访问外部类的私有成员。
这是因为:在非静态内部类对象里,保存了一个寄存它的外部类对象引用。当调用非静态内部类的实例方法时,必须有一个非静态内部类实例,而非静态内部类实例必须寄存在外部类实例里。
非静态内部类对象单独属于外部类的某个对象,就像外部类的成员变量一样。
先有外部类对象,才能再有内部类对象。
<anchor> 非静态内部类中不允许有静态属性和方法(和初始化块)
关于JAVA的类加载顺序:
public class Outer {
class NotStaticInner {
static int i = 0; //这样写是不合法的.
static final int CONSTANT = 0; //这样写是合法的
}
}
首先加载类,执行其static变量初始化,接下来执行对象的创建,初始化非静态成员变量;
如果我们要执行代码中的变量i初始化,那么必须先加载Outer,再加载NotStaticInner,初始化静态变量i。
问题就出在加载NotStaticInner上面,把NotStaticInner看成Outer的非静态成员变量,它的加载必须在外部类对象创建以后进行。要加载NotStaticInner必须在实例化Outer之后完成,而JVM要求所有的静态变量初始化必须在对象创建之前完成,这样便产生了矛盾。
常量之所以可以 (不论有无static),因为 JAVA 在编译期就确定所有常量,放到常量池当中。
[注] 嵌套类 = 静态内部类 (ThInJa.P193);非静态内部类的“静态”属性和方法都可以通过放在外部类中定义而解决,因为内部类的对象也可以轻松调用他们。
(外部类的)静态成员不能 访问 非静态成员(非静态内部类)。Cannot make a static reference to the non-static field, 访问时它都不一定有。
非静态内部类对象必须寄存在外部类对象里,但外部类对象却不必一定有非静态内部类寄存其中。(fk.P202)
121.静态内部类。
当一个静态内部类对象存在,并不一定存在对应的外部类对象,所以静态内部类的实例方法不能直接访问外部类的实例方法。
外部类可以通过 StaticInner.attribute_name 访问其静态成员。
创建内部类对象:Outer.StaticInner sInner = new Outer.StaticInner();
122.在修饰类方面,static只能修饰内部类。Illegal modifier for the class; only public, abstract & final are permitted.
123.总结:①普通的成员内部类可以访问外部类的普通的属性和方法。②普通的成员内部类可以看作外部类的一个普通的属性(所以可以访问外部类的其他成员)。普通内部类对象必须寄宿在外部类对象里面。必须先有外部类对象,才能有内部类对象。③静态内部类加了static修饰以后,静态内部类对象存在,它的外部类对象不一定存在,静态内部类不能访问外部类的普通的属性和方法,但是静态内部类可以直接访问外部类的静态的属性和方法。
124. Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 ——最常见的异常
at cn.bjsxt.array.Test01.main(Test01.java:9)
看异常信息 = 上下左右找你认识的东西(线索);有些人,甚至拆开每个单词都不认识,但合起来他知道数组越界了。常见异常就那么几个,熟能生巧。3 指的是第 3 个索引越界了。
125. (1)数组是相同数据类型的有序集合
(2)数组也是对象。数组元素相当于对象的成员变量 (详情请见内存图 00:26:15@e52)
(3)数组长度是确定的,不可变的。如果越界,则报:ArrayIndexOutOfBoundsException
126. 操作对象就是操作它的引用,对象数组每个元素里放的是对象的引用。
127. length是数组对象的final属性。
128.数组的使用:声明、创建数组对象、初始化。大部分“容器”的底层实现都是数组。
129.初始化:默认、动态(for)、静态(回车排版、必须和声明一起用)。
130. new默认初始化:数组元素相当于对象的成员变量。数字0,布尔false,charu0000,引用null。
131.final声明的引用,意思是不能再次指向别的对象;但指向对象的属性值能不能改,取决于这个类有没有提供对应的set方法。String类里的private final char value[],之所以不能改是因为没有提供方法,而不是因为final。
132.String是类,其length()方法只是将value.length返回。String类称为不可变字符序列!
*133. @Deprecated [ˈdeprəkeɪt] 注解的方法会有删除线,表示不推荐、已淘汰的方法,往往有更佳的解决方案。
134.String类的常用方法:多重构造器、length()、isEmpty() 用value的长度判断、charAt() 做了越界检查、equals() 00:25:38@e54、equalsIgnoreCase() 忽略大小写的相等、startWith()/endsWith() 看是不是参数开头/结尾、indexOf(→)/lastIndexOf(←) 返回第一个char的索引或-1、substring()、replace() 不会改变原字符串的内容、split()、trim() 去除只在首尾的所有空格、toString()、toCharArray() 疑问:为什么不直接返回value?、toLowerCase()/toUpperCase()。——可以看看源码
135.String全等==:指向常量池,编译器优化 (javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果);new两个对象,“两个”一定不全等。String相等equals():内容相等。
136.replace()的参数是字符和字符串(CharSequence是接口),replaceAll()的参数是正则表达式;相同点是都是全部替换。只想替换第一次出现的,可以使用 replaceFirst()。
137.使用 + 拼接字符串,循环1000次,1000个对象就出现了。new String(“a”) 还有俩对象 (00:12:25@e55)。如果是服务器程序,对象数*线程数,空间消耗将是灾难。
138.可变字符序列:StringBuilder(线程不安全/效率高),StringBuffer(线程安全/效率低)。使用局部变量,一般使用StringBuilder。
139. eclipse: 查看源码时,使用F4或右键,查看运行层次Open Type Hierarchy。
140.StringBuilder(和StringBuffer同继承自抽象类AbstractStringBuilder),默认初始化长度为16;或指定长度;若指定内容,则长度再加16。最强的方法是append(),扔true也做字符串连接,且return this可用于写方法链。
141.使用StringBuilder做字符串的拼接才是正解,new StringBuilder(“a”) 全程只有两个对象。
142.append()方法的扩容函数(append→ensureCapacityInternal→expandCapacity),每次长度不够使先把value长度”乘2加2”,还不够直接设所需要的大小;value = Arrays.copyOf(value, newLength) 内部实际建了个新数组用System.arraycopy()把老的替换了。老数组被GC回收掉。
143.delete() 删除起止索引[0起]内容_包头不包尾+同则不作为、replace()直接改数组、insert() 数组是查询方便,而插入删除修改不方便,需要“移位”、reverse()。——可以看看源码
144.仿照StringBuilder和ArrayList类源码,自己写一个容器类MyArrayList,选择实现其中的一些越界检查rangeCheck()、扩容extendCapacity()、CURD等方法。Create/Update/Read/Delete
145.System.arraycopy()是一个native修饰的静态方法,如果新数组比原数组的length小则会抛出java.lang.ArrayIndexOutOfBoundsException异常。Arrays.copyOf()不会因为长度问题而报错,因为Arrays.copyOf()的返回值是在内部 new 好的新数组,其大小就等于newLength。但是Arrays.copyOf()方法最后也是调用System.arraycopy()的,不过由于之前已经对数组进行了处理,所以不会报出异常。(了解:关于native关键字涉及到JNI,native修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言,如C和C++实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问)
146.多维数组。数组元素还是数组 ( int[][] )。
声明和初始化从高维到低维 (第一维都不知道多少怎么知道第二维!而第二维多少都有可能!见下图148)。
147.二维数组静态初始化:
int[][] a = {{1,2}, {3,4,0,9}, {5,6,7}}; // 不必须是规则矩阵形式
148.二维数组动态初始化:
int[][] a = new int[3][];
a[0] = new int[2]; a[1] = new int[4]; a[2] = new int[3];
a[0][0] = 1; a[0][1] = 2;
a[1][0] = 3; a[1][1] = 4; a[1][2] = 5; a[1][3] = 6;
a[2][0] = 7; a[2][1] = 8; a[2][2] = 9;
149.矩阵的加法和打印,二维数组实现。同阶i和j,双重for。
150.数组拷贝 Arrays.copyOf()/System.arraycopy()、数组排序Arrays.sort()、数组二分查找 Arrays.binarySearch() 找不到返回 <0、数组json打印 Arrays.toString()、填充Arrays.fill()。(Arrays.asList()和对象排序自定义compareTo()详见”容器”)
API:在 System 类提供的设施中,有标准输入、标准输出和错误输出流;对外部定义的属性和环境变量的访问;加载文件和库的方法;还有快速复制数组的一部分的实用方法。
151.自己实现:冒泡排序(我好像一直混淆了"选择排序")、二分查找(先排序)。
152.命令行参数:①java Test a b "c d" 有空格就用双引号引起来作为一个参数。
②eclipse:Run Configurations
153.增强for循环:for(DataType ai : array)。可打foreach出来。
常用类
154.包装类(Wrapper Class):将基本类型数据转换成对象。value作基本数据类型的私有final属性,外面包了层对象。
155.Integer继承了父类Number里的许多方法。
Integer.MAX_VALUE/Integer.MIN_VALUE、toHexString()、valueOf()、parseInt()、intValue()、equals()。数字转字符串,+"" 即可。
156.自动装箱和拆箱。JDK5.0在编译器(不是虚拟机)里做了手脚。
Integer b = null; int c = b; 报空指针异常,因为编译器改进代码,私下调用了intValue()方法。
157. Integer a = 1234; Integer b = 1234; 此时a != b。
Integer a = 123; Integer b = 123; 此时a == b。
关于缓存:[-128, 127] 之间的数,仍然当做基本数据类型来处理,为了提高效率。基本数据类型还是比对象快!
详见 新浪博客,Integer.valueOf(int i)返回一个表示指定的int值的Integer实例,new Integer(i)产生一个新的Integer对象。Integer.valueOf()内部调用了 IntegerCache.cache[i + offset] 优化方法,当-128=<i<=127的时候,返回的是IntegerCache中的数组的值;当 i>127 或 i<-128 时,返回的是Integer类对象。
158.时间处理类。Date类有两个包util工具用类和sql数据库用类,导包时不要导错。
格里高利历是公历。
159.Date类。(时间戳)
可以推负数到1970年以前。毫秒和秒是千进位。
160. Date()的构造器里用this()传参System.currentTimeMillis()。
技巧:先写带参数的构造器,然后使用this()来调用之,实现无参的构造器。
161.toGMTString() 转换格林尼治时间(已废弃)、toLocaleString() 转换本地日期习惯(已废弃)。已废弃的方法,API里会提供替换方案(replaced by…)。一开始Date类很强大,后来一分为三。
162.long get/setTime()、before()/after() 比较时间大小[可以自己写]、toString()。
163.抽象类DateFormat和它的一个实现SimpleDateFormat,用于完成字符串和时间对象的转化。注意是text包。
技巧:Ctrl+T去看该抽象类有哪些(官方)子类实现可以用。
DateFormat df = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss"); 格式化字符串见SimpleDateFormat的API
format()[时间→字符串] 和 parse()[字符串→时间] 方法。
164.Calendar日历抽象类,月份常量0-11(Jan.-Dec.),周日常量是1,周六是7。用于完成long类型的数和日期进行转换。计算机认识long,人认识年月日时刻,此类搭桥。GregorianCalendar格里高利历实现类。
*165.使用chm版的api索引。学写文档注释就看一看jdk源码文档注释和文档显示效果,几个标签记住就会用。
166. eclipse: Ctrl+shift+o (organize imports)可以导入需要的包。
167. eclipse: Ctrl+shift+s 可以保存所有未保存的文件。
168.日历类常用方法:①各种重载set(使用Calendar.常量),其中set(field, value)方法可以单独指定,如c.set(Calendar.DATE, 25);不设的话采用当前时间(与DateFormat有区别) ②获取特定信息get(field); 获取时间Date getTime()/long getTimeInMillis() ③setTime(Date d) ④日期计算add(field, value),加负为减。
169.获取本月天数:移动下月,设置首日,首日减一。(DAY_OF_WEEK代表“星期几”)
法一:
c.add(Calendar.MONTH, 1);
c.set(Calendar.DATE, 1);
c.add(Calendar.DATE, -1);
int days = c.get(Calendar.DATE);
法二:
c.getActualMaximum(Calendar.DATE);
*170.输出时注意print(); 和 println();
171. 解题技巧: 积极心态调整——这事儿能不能做,先说可以做,再想办法怎么做(回去哪怕加班呢)。能做多少做多少(总比不做强),做着做着就有感觉了(慢慢一点点改进);先把简单的做了,难点一个个突破,然后就over了。这样、机会越来越多,工资越来越多。(另见:第50条)
172. eclipse: Ctrl+D直接删除当前行,可能会和emmet插件冲突,需要unbind该命令重启再设置。
173.io.File类:文件(目录也是文件)路径名的抽象表示形式。与文件相关的操作就查它的API。
路径分隔符直接写/也没关系。
File f = new File("c:/file"); // 现在对象f就代表这个文件
File f2 = new File("c:/");
File f3 = new File(f2, "file");