151 个建议 读书笔记

151个建议读书笔记

普通


1、  当使用long 类型的数据时,要将值后的l 写为L ,小写的l 容易与数字1 混淆

例子:   long num = 3l;    long num = 3 L ;


2、  务必让常量的值在运行时保持不变:

例子: public static final int CANNOT_CHANGE = new Random.nextInt();

此时的常量在运行时会变,不能这样写

建议: 常量保存到常量类中


3、  三目运算的后面两个值的类型一定要相同:

例子: int num = a<100? 90 : 100

Int num = a< 100? 90 : 100.0  两个操作数的类型不同

当两个操作数不同时的转换规则(只做了解):


4、  方法重写: 了解


5、  自增的错误

例子:

Int num = 0 ;

for(int a = 0 ;a<10;a++){

num=num++;

}

错在 num = num++  改为 num++  就可以了

对java 中 num= num++ 的理解:

1、  int temp = num

2、  num =num+1

3、  return  temp

Num = num++  这句话在c++ y语言中是正确的,在java和php中是错误的

扩展:复习 num++  ++num  num--  --num

num ++ :     int num = 0 ;

int  sum = num++;

当运行int  sum = i++; 这句话时 ,先将num此时的值即0复制到临时区,

然后将num的值0进行加1 ,此时num=1然后再返回 临时区中的0 给sum

Int  sum  = (num++)+(num++);  在没有int  sum = num++;这句代码时sum 值为1

Int  sum  = (num++)+(num++)+(num++);在没有上面两句代码时 sum值为 3

int num = 0 ;

Int  sum = num++;

sum  = (num++)+(num++);

sum  = (num++)+(num++)+(num++);

此时 sum 的值为 12;num值为6

int num = 10;

int sum = num--;    返回10,num为9

sum  = (num--)-(num--);  返回9 num为8 – 返回8 num 为7

sum  = (num--)-(num--)-(num--); 返回7 num为6   7-6-5

此时sum 的值为-4,num值为5


6、  静态引入:

一段代码中不能有多个静态引入,否则代码难以阅读;本类中的属性和方法不能覆盖静态引入的类的属性和方法,否则会触发编译器的最短路径原则(即当发生覆盖时会使用本类中的属性和方法而不会使用静态引入的属性和方法。

个人建议: 除断言外尽量少的使用静态引入


7、  显示声明UID:

在编写一个实现了Serializable接口的类,需要增加一个Serial Version ID (流标识符),即类的版本定义,可以显式声明和隐式声明,

显式声明:

Private static final long serialVersionUID = xxxxxxL;

Jvm 在进行反序列化时,会比较数据流中的serialVersionUID 与类中的serialVersionUID 是否相同,如果相同,则认为类没有发生改变,可以把数据流load为实例对象;如果不同jvm会抛出InvalidClassException. 这是一个非常好的校验机制,可以保证类在网络和磁盘中“滚过”一次,仍能做到“出于泥而不染”,完美地实现类的一致性

使用场景: 当类的改动不大时,jvm是否可以把以前的对象反序列化过来,就依靠显式声明serialVersionUID  ,向虚拟机撒谎“类的版本没有改变”,这样,我们编写的类就实现了向上兼容。

序列化: 实现序列化的目的是为了持久化,实现了Serializable 接口,可以在网上传输也可以本地存储,通过对象序列化过程,把一个对象从内存块转化为可传输的数据流,然后通过网络发送给消费者那里,并进行反序列化,生成实例对象。

可以自己写一个SerializationUtils 工具类进行序列化和反序列化

serialVersionUID 的使用例子:

8、   使用switch 的时候记住使用break 防止穿透, default 也要使用 break


9、  避免instanceof 非预期结果


10、              发布应用系统时禁止使用类文件替换的方式,整体war包发布才是完全之策

 

11、              用偶判断,不用奇判断

num%2==0?“偶数”:“奇数”;

在被除数小于除数的情况下 商0余数为被除数

num = -1 ;   -1%2 余数为-1

如果 是 num%2 == 1 ?“奇数”:“偶数”,-1!=1 所以 num= -1 为 偶数;

用偶判断  num% 2 == 0 ? “偶数”:”奇数”, -1!= 0 ,所以 num=-1 为奇数

java中取余数(%)的算法:


12、              注意数据类型

Java是先运算然后再进行类型转换的,当num1*num2*num3 的运算结果超过了int 类型的最大值

,所以运算结果是负值,再转为long型也是负值了

long mul ,int num1 ,int num2 ,int num3   num

错误: long  mul = num1*num2*num3

正确: long  mul = num1 * num2L *num3   L 类型千万不能放在最后面,如下:

不建议:  long  mul = num1 * num2*num3L  如果num1*num2的值就已经超过int的范围再用num3L 也无济于事


13数据边界

当用户输入的order值为2147483647(int能表示的最大值)时,代码中的order+cur 会超过int能表示的最大范围,数据运算要做边界测试

14、提防包装类的null值。 例如: Integer的拆箱过程是调用包装对象的intValue方法,如果Integer类型的变量值为null则会报空指针异常。包装类型参与运算时,要做null值校验

15、尽量不要用包装类进行大小比较,如果非要比较要使用包装类的comparator,而不能直接使用>,<,==l来比较包装类,类是有地址的

16、优先使用整型池

Integer  的整型池的范围为-128到127,当数值在整型池范围内切需要用Integer时,使用Integer.valueOf( ); 生成包装类实例

17、优先选择基本类型:

int 可以加宽转变成long,然后再转变成Long对象,但是不能直接转变成Long的对象。 即: 基本类型可以先加宽,再转变成宽类型的包装类型,但不能直接转变成宽类型的包装类型。

下面代码的编译和运行,会一直输出基本类型的方法被调用

18、 不能重写静态方法,但是可以隐藏静态方法;

注意:通过实例对象访问静态方法或者静态属性是不好的习惯

注意: 通过对象调用静态方法,jvm则会通过对象的表面类型查找到静态方法的入口

19、  构造函数要尽量简化

20、 尽量不要在构造函数中初始化其他类

如果几个类的构造函数中都在初始化另一个类,并且形成了死循环,那样会造成stackOverflowError

栈溢出

21、构造代码块: 构造代码块不会插入到使用了this关键字的构造函数中;super的在super后插入

上面的代码等价于下面的代码:


22、使用静态内部类提高封装性

只有在是静态内部类的时候才能把static 放在类 class 的前面,其他任何时候static 都不能修饰class。 在下面的例子中仍然可以在外部使用 new Home 来构造对象,只是要引入Person.Home

例:    public  class  Person {

/** 姓名*/

Private  String   name;

/**家庭*/

Private  Home  home ;

//静态内部类

Public  static  class  Home{

/** 地址*/

Private  String  address;

/**电话*/

Private  String  phoneNum;

}

}

23、 使用匿名类的构造函数 (39 )

匿名类虽然没有名字,但是可以有构造函数的,它用初始化块或叫构造函数块来代替

理解三句代码: List  one =  new ArrayList () ;

List   two = new ArrayList () {};

List  three = new ArrayList () { { } };

一个类中的构造函数块可以是多个,也就是说可以出现如下代码:

List  three = new ArrayList () { {} {} {} {} };

24 、保证工具类的不可实例化; 将构造函数设为私有的,并且在构造函数中抛出异常。工具类不可实例化后,注意不要被继承了,并且子类还能实例化, 子类实例化会使父类初始化,而这里的工具类的构造器时private 的 ,不能被子类访问

Private utilClass(){

throw new  error (“这是工具类,请不要实例化!”);

}


25、避免对象的浅拷贝

可以理解浅拷贝和深拷贝

浅拷贝:   一个类Student  实现了 cloneable 接口,并重写了clone 方法,就可以进行拷贝

浅拷贝是 一个对象B 拷贝自 对象A时,A的属性值修改时,B的属性值也会自动更改。说明浅拷贝拷贝的是 对象的一个引用地址,所以被拷贝对象改变,拷贝出的对象也会改变。

深拷贝: 将拷贝得到的对象 自行设置属性值,这样拷贝出来的对象自成一体,不会受“母体”影响,

和new 生成的对象没有区别


26、 类最好重写 toString () 方法。   Println 和print 的实现机制 ,如果参数是基本数据类型和String就直接打印,如果参数是自定义类型则调用类的toString () 方法


27、 使用equals  容易犯的错误:  “  A  ”.equals(“A” ) ; 是会返回false的, 因为前面的A的有空格,后面的A没有 。  equals 方法的自反性原则

mylist.contains(“a”);   lIst 检查是否包含元素时,是通过调用对象的eqauls()方法进行逐一判断,有一个相等就返回 true

使用eqauls 的时候要注意判 null

Equals 的自反性 和对称性


28、 重写equals 方法的时候必须重写hashcode 方法


29、直接使用string 字符串常量池

b1、b2、b3的结果分别为true 、false、true

字符串常量池的原理:

New 一个String 对象时,是不会去检查字符串常量池中是否已经有该字符串字面量的String 的,所以b2的结果为false

30、单元测试: 正常测试、边界测试、异常测试

31、string的 replaceall 的第一参数是正则表达式

32、 1+2+“注意区别” 和 “注意区别”+1+2  的 区别

33、正则表达式对象和匹配器

34、 常用中文汉字按拼音排序使用java 的collator ,如果有晦涩的汉字则需要pinyin4j等开源jar 将汉字转换为拼音了。

35、集合的拷贝也是浅拷贝

36、arrayList 的默认长度是10,当元素数量达到长度临界点时,会扩容1.5倍。 当长度为10的arrayList 添加第11个元素时,arrayList 会自动扩容, 新的长度为  10* 1.5 +1  =  16

37、 这段代码输出结果为一的原因: 基本数据类型不能作为asList() 方法的参数,所以编译器会将整个int 数组作为一个参数,将int 改为Integer 则输出的结果为5

38、 asList 方法产生的List  对象不可更改,该方法产生的对象不具有 add和remove 方法,只有get、set、size、

Contains 、和 toArray 方法。除非能非常确定该集合不会改变集合长度,否则此方法慎用

39、arrayList 采用下标遍历效率高于foreach 遍历; LinkedList 采用foreach 遍历效率高于下标遍历,LinkList 是双向链表

40、频繁的插入和删除元素时使用LinkList 效率更高,在处理大批量的添加和删除时LinkList的效率是ArrayList的40倍,但是修改元素ArrayList的效率更高。   而两者的add  添加效率差别不是很大

41、是有版本区别的


重要


14、使用序列化类的私有方法巧妙解决部分属性持久化问题


16、易变业务使用脚本语言编写

 


17、慎用动态编译

 


22、用整数类型处理货币


23、不要让四舍五入亏了一方:

要根据不同的场景,慎重选择不同的舍入模式,以提高项目的精准度,减少算法损失


30、不要随便设置随机种子


40、匿名类的构造函数很特殊


41、让多重继承成为现实(利用内部类)


48、在equals中使用getCLass() 进行类型判断


53、注意方法中传递的参数要求


69、列表相等只关心数据元素

时间: 2024-10-06 17:43:07

151 个建议 读书笔记的相关文章

编写高质量代码:改善Java程序的151个建议-学习笔记

java中通用的方法和准则 1.不要让常量和变量中出现易混淆的字母 比如: long i = 1l; 别人很难一下子看清楚是11还是1l,所以应该这样写1L. 命名规范: 1.包名全部小写 2.类名首字母大写 3.方法名称,首字母小写,后面单词首字母大写 4.常量要用大写,并且用下划线隔开 5.变量要用小写 2.莫让常量蜕变成变量 interface Const { public static final int RANDOM_NUM = new Random().nextInt(10); }

改善python程序的91个建议读书笔记1

引论 建议1:理解pythonic的概念 pythonic也许可以遮阳定义:充分体现python自身特色的代码风格. python中两个变量交换只需一行: a,b= b,a 遍历一个容器时可以为: for i in alist: do_sth_with(i) 打开文件,需要安全的关闭文件可以为: with open(path,'r') as f: do_sth_with(f) 如果想倒序输出一个列表可以这样: printlist(reversed(a)) 写pythonic程序需要对标准库有充分

改善python程序的91个建议读书笔记2

第二章 编程惯用法 建议8:利用assert语句来发现问题 断言在很多语言中都存在,它主要为调试程序服务,能够快速方便的检查程序的异常或者发现不恰当的输入等. assert语法如下 assert expression1 ["," expression] 其中计算expression1的值会返回True或者False,当值为False的时候会引发AssertionError,而expression2是可选的,常用来传递具体的异常信息.实际在执行过程中调用了if __debug__ and

《编写高质量代码:改善Java程序的151个建议》笔记

To fight the unthinkable,you have to be willing to do the unthinkable. 不要在循环中使用try catch,应该放在循环的外面. One Line 务必让常量的值在运行期间保持不变. 保证三元操作符中的两个操作类型一致. 反序列化时构造方法不会执行. 在序列化类中,不使用构造方法为final变量赋值. 避免为final变量复杂赋值. 发布应用系统时,禁止使用类文件替换方式,整体WAR包发布才是万全之策. 包装类型参与运算时,要

《编写高质量代码188个建议》读书笔记

第一章  JavaScript语言基础 一.代码的执行速度决定的因素是: 1.代码量少,运行速度不一定快 2.代码量多,速度也不一定慢 建议1:警惕Unicode代码 javascript代码每个字符都两字节,这样函数名和变量名都可以使用中文来命名 1 <script> 2 var 人名 = "张三"; 3 console.log(人名); 4 5 function 技术(开发){ 6 console.log(开发); 7 } 8 9 技术("哈哈");

转载-------编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议1~5)

阅读目录 建议1:不要在常量和变量中出现易混淆的字母 建议2:莫让常量蜕变成变量 建议3:三元操作符的类型务必一致 建议4:避免带有变长参数的方法重载 建议5:别让null值和空值威胁到变长方法              The reasonable man adapts himself to the world; The unreasonable one persists in trying to adapt the world himself. 明白事理的人使自己适应世界:不明事理的人想让世

《C#图解教程》读书笔记之五:委托和事件

本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.委托初窥:一个拥有方法的对象 (1)本质:持有一个或多个方法的对象:委托和典型的对象不同,执行委托实际上是执行它所"持有"的方法.如果从C++的角度来理解委托,可以将其理解为一个类型安全的.面向对象的函数指针. (2)如何使用委托? ①声明委托类型(delegate关键字) ②使用该委托类型声明一个委托变量 ③为委托类型增加方法 ④调用委托执行方法 (3)委托的恒定性: 组合委托.为委托+=增加

《卓有成效的程序员》----读书笔记二

六大方面对比Launchy和TypeAndRun(TAR) 对于快速启动工具,很多人都有自己的偏好,多次听到朋友介绍Launchy的好,虽然自己一直在使用着TAR,还是克制不住对于好软件的渴求,下载Launchy进行试用.很多软件都是有一个试用期的,也许新的软件确实不错,但是你习惯了以前使用的那个软件.今天就比较客观的将Launchy和TAR进行一下对比,从界面.上手速度到功能.自定义,以及软件的稳定性.占用资源进行详细的比较. [界面美观]Launchy:毫无疑问这是它的强项.1.0正式版自带

【转】《windows核心编程》读书笔记

这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入,但应该是合理的.开头几章由于我追求简洁,往往是很多单独的字句,后面的内容更为连贯. 海量细节. 第1章    错误处理 1.         GetLastError返回的是最后的错误码,即更早的错误码可能被覆盖. 2.         GetLastError可能用于描述成功的原因(CreatEvent)