改善java程序的151个建议--笔记一

一、Java开发中通用的方法和准则

1、不要在常量和变量中出现易混淆的字母

eg:long i=1l,这是11还是lL呢,建议使用大写的方式;

2、不要让常量变成变量

eg:public static final int RAND_CONST=new Random().nextInt();

3、三元符的类型务必一致

eg:String s=String.valueOf(i<100?90:100.0);

4、避免带有变长参数的方法重载

eg:calPrice(int price,int discount);

calPrice(int price,int... discounts);

5、别让null值和空值威胁到变长方法

eg:methodA(String str,Integer... is);

methodA(String str,String... strs);

Test:methodA(“China”);

methodA(“China”,null);

6、覆写变长方法也要循规蹈矩

Eg:parent:method(int price,int... discounts);

Children:method(int price,int[] discounts);

7、警惕自增陷阱

Eg:int count=0;for(int i=0;i<10;i++){count=count++};输出结果为0

8、不要让就语法困扰

Eg:goto语句、methodA:methodB();

9、少用静态导入

10、不要在本类中覆盖静态导入的变量和方法

11、养成良好的习惯,显式声明UID

Eg:序列化

12、避免用序列化类在构造函数中为不变量(final修饰)赋值

13、避免为final变量复杂赋值

Eg:public final String name=initName();

Public String initName(){return “hello”;}

反序列化时final变量在以下情况下不会被重新赋值:

1)通过构造函数为final变量赋值;

2)通过方法返回值为final变量赋值;

3)Final修饰的属性不是基本类型;

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

15、Break万万不可忘

Switch....case中....

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

例如通过java中的ScriptEngine调用javascript中的方法

17、慎用动态编译:在运行期间直接编译.java文件,执行.class,将java类信息写入到字符串中,然后运行期间调用相关接口执行字符串中的java信息

18、避免instanceOf非预期结果,注意instanceOf成立的条件是操作数左右两边要有继承或者实现关系,否则编译会报错

Eg:’A’ instanceOf Character、new Date() instanceOf String,

19、断言绝对不是鸡肋:assert<布尔表达式>:<错误信息>

20、不要只替换一个类:发布应用系统时禁止使用类文件替换方式,整体war包发布才是完全之策

二、基本类型

21、判断奇偶数,用偶判断,不用奇判断

Eg:i%2==1?”奇数”:”偶数”;-1的时候会出现问题

正确使用:i%2==0?”偶数”:”奇数”;

22、用BigDecimal和整形类型处理货币

23、不要让类型默默转换

Eg:public static final int LENGTH_SPEED=30*10000*1000;

long v=LENGTH_SPEED*60*8会出现负数,因为计算的时候,先是运算再进行类型转换的,三个数都是int类型,计算后超出int的最大值,所以计算结果为负值;

正确的方式:long v=1L*LENGTH_SPEED*60*8;计算的时候后面的都会转换成为长整形

24、整形类型的边界值需要考虑,在进行单元测试的时候,进行int类型参数测试的时候,需要考虑下面几个值:0、正最大、负最小

25、不要让四舍五入亏了一方,例如在做银行、金融相关行业的系统的时候,要根据不同的场景,慎重选择不同的舍入模式,以提高项目的精准度,减少算法损失

26、提防包装类型的null值:包装类型参与运算时候,要做null值校验

27、谨慎包装类型的大小比较

Eg:Integer a=new Integer(100);

Integer b=new Integer(100);

a==b:false,a>b:false,a<b:false;

28、优先使用整形池:基本类型的装箱动作是通过valueOf方法来实现的,对于int类型转换为Integer对象,如果int值的范围在-128到127之间,那么它直接从cache数组中获得,不在该范围的int类型则通过new生成包装对象,通过包装类的valueOf生成包装实例可以显著提高空间和时间性能

29、优先选择基本类型

Eg:int i=0;

test(i);

test(Integer.valueOf(i));

public static void test(long i){}

public static void test(Long i){}

在进行自动装箱的过程中,基本类型可以先加宽,再转变成宽类型的包装类型,但是不能直接转变成宽类型的包装类型。Int可以加宽变成long类型,然后再转变成为Long对象,但是不能直接变成Long对象。

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

Eg:Random random=new Random(1000);产生随机数的种子被固定了

Java中产生随机数:Random、Math.random();

三、类对象及方法

31、在接口中不要存在实现的代码

Interface S{public void doSomething();} interface B{S s=new S(){public void dos{}}}

32、静态变量一定要先声明后赋值

Eg:static{i=100;} public static int i=1;

33、不要覆写静态方法,当父类中定义了一个静态方法后,子类中应不要覆写静态方法,类中定义静态方法或属性应该通过类名直接访问,通过实例对象访问静态方法或属性不是好的习惯;

34、构造函数应尽量简化,否则可能会出现因初始化的时候变量的不一致;

35、避免在构造函数中初始化其他类

36、使用构造代码块精炼程序:构造代码块会在每个不同参数的构造方法中都执行一次,先执行构造代码块,再执行构造方法,它并不是在构造函数之前运行的,它依托于构造函数执行,我们可以把构造代码块运用到如下场景中:1:初始化实例变量2:初始化实例环境;

37、构造代码块会想你所想,在构造方法中使用this和super的时候,构造代码块已经替你考虑好了,如果在有参数构造方法中使用this(),是不会再重新执行构造代码块的,所以要灵活运用;

38、使用静态内部类加强类的封装性和提高了代码的可读性

39、使用匿名类的构造函数:new ArrayList(){};new ArrayList(){{}{}{}}

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

41、灵活使用内部类,让多重继承成为现实;

42、让工具类不可实例化最好的方式是:这样也不能利用反射机制进行实例化

public class Utils{

private Utils(){

Throws new Error(“don’t intstance me!!”);

}}

43、避免对象的浅拷贝:

Object提供的clone方法只是一种浅拷贝方式,也就是说它并不会把对象的所有属性全部拷贝一份,而是有选择性的拷贝,其拷贝规则如下:

基本类型:则拷贝其值

对象:拷贝地址引用,也就是说新拷贝出的对象与原有对象共享该实例变量,不受访问权限的限制。

String字符串:拷贝的也是一个地址,是个引用,但是在修改时,它会从字符串池(String pool)中重新生成新的字符串,原有的字符串对象保持不变,在此我们可以认为String是一个基本类型。

44、推荐使用序列化的方式实现对象的拷贝:参考我的博文,java对象的浅拷贝和深拷贝:http://blog.csdn.net/harderxin/article/details/41694747

45、覆写equals方法时不要识别不出自己(见代码)

//	public boolean equals(Object obj) {
//		if(obj instanceof Person3){
//			Person3 p=(Person3)obj;
	//去掉trim()
//			return name.equalsIgnoreCase(p.getName().trim());
//		}
//		return false;
//	}

46、equals应该考虑null值情景

//  第二个版本----建议46
//	@Override
//	public boolean equals(Object obj) {
//		if(obj instanceof Person3){
//			Person3 p=(Person3)obj;
//			if(p.getName()==null||name==null){
//				return false;
//			}else{
//				return name.equalsIgnoreCase(p.getName().trim());
//			}
//		}
//		return false;
//	}

47、为了防止继承,建议在equals中使用getClass进行类型判断,而不是使用instanceOf

//  第三个版本----建议47
	@Override
	public boolean equals(Object obj) {
		if(obj!=null&&obj.getClass()==this.getClass()){
			Person3 p=(Person3)obj;
			if(p.getName()==null||name==null){
				return false;
			}else{
				return name.equalsIgnoreCase(p.getName().trim());
			}
		}
		return false;
	}
	

48、覆写equals方法必须覆写hashcode方法:

HashMap:底层处理机制是以数组的方式保存Map条目(Map Entry)的,这其中的关键是这个数组下标的处理机制:依据传入元素hashCode方法的返回值决定其数组的下标,如果该数组位置上已经有了Map条目,且与传入的键值相等则不处理,若不相等则覆盖;如果数组位置没有条目,则插入,并加入到Map条目的链表中,同理,检查键是否存在也是根据哈希码确定位置,然后遍历查找键值的。HashCode的值我们可以使用org.apache.commons.lang.builder包下的一个哈希码生成工具HashCodeBuilder生成

49、推荐覆写toString方法:java提供默认的toString方法不友好,打印出来只有机器能看懂,其格式为类名+@+hashCode,所以建议覆写toString方法,便于我们进行调试

50、使用package-info类为包服务:在需要用到包的地方,可以考虑一下这个特殊的类

51、不要主动进行垃圾回收:在应用程序中不要直接使用System.gc()来主动对垃圾进行回收,即使经常出现内存溢出也不要调用

时间: 2024-12-29 23:55:43

改善java程序的151个建议--笔记一的相关文章

[ 转 ]编写高质量代码:改善Java程序的151个建议

记得3年前刚到公司,同桌同事见我无事可做就借我看<编写高质量代码:改善Java程序的151个建议>这本书,当时看了几页没上心就没研究了.到上个月在公司偶然看到,于是乎又找来看看,我的天,真是非常多的干货,对于我这种静不下心的人真是帮助莫大呀. 看完整本书,也记了不少笔记,我就分享一部分个人觉得有意义的内容,也为了方便以后自己温习. --警惕自增陷阱 i++表示先赋值后自增,而++i表示先自增后赋值.下面的代码返回结果为0,因为lastAdd++有返回值,而返回值是自增前的值(在自增前变量的原始

转载-------编写高质量代码:改善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. 明白事理的人使自己适应世界:不明事理的人想让世

编写高质量代码改善java程序的151个建议——导航开篇

2014-05-16 09:08 by Jeff Li 前言 系列文章:[传送门] 下个星期度过这几天的奋战,会抓紧java的进阶学习.听过一句话,大哥说过,你一个月前的代码去看下,惨不忍睹是吧.确实,人和代码一样都在成长,都在变好当中.有时候只是实现功能的编程,长进不了呀. 博客提供的好处就可以交流,讨论的学习方法你们应该知道. 在这里,我会陆陆续续的进行对<编写高质量代码改善java程序的151个建议>看法,希望大家点击交流. 正文 看这本书原因   1.项目做的只是实现功能,然而没有好好

编写高质量代码改善java程序的151个建议——[1-3]基础?亦是基础

原创地址:   http://www.cnblogs.com/Alandre/  (泥沙砖瓦浆木匠),需要转载的,保留下! Thanks The reasonable man adapts himself to the world;the unreasonable one persists in trying to adapt the world to himself. -萧伯纳 相信自己看得懂就看得懂了,相信自己能写下去,我就开始写了.其实也简单-泥沙砖瓦浆木匠 Written In The

编写高质量代码改善java程序的151个建议——[110-117]异常及Web项目中异常处理

原创地址:http://www.cnblogs.com/Alandre/(泥沙砖瓦浆木匠),需要转载的,保留下! 文章宗旨:Talk is cheap show me the code. 大成若缺,其用不弊.大盈若冲,其用不穷.  <道德经-老子>最完满的东西,好似有残缺一样,但它的作用永远不会衰竭:最充盈的东西,好似是空虚一样,但是它的作用是不会穷尽的 Written In The Font 摘要: 异常处理概述 学习内容: 建议110: 提倡异常封装 建议111: 采用异常链传递异常 建议

编写高质量代码:改善Java程序的151个建议 --[52~64]

编写高质量代码:改善Java程序的151个建议 --[52~64] 推荐使用String直接量赋值 Java为了避免在一个系统中大量产生String对象(为什么会大量产生,因为String字符串是程序中最经常使用的类型),于是就设计了一个字符串池(也叫作字符串常量池,String pool或String Constant Pool或String Literal Pool),在字符串池中容纳的都是String字符串对象,它的创建机制是这样的:创建一个字符串时,首先检查池中是否有字面值相等的字符串,

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

阅读目录 建议16:易变业务使用脚本语言编写 建议17:慎用动态编译 建议18:避免instanceof非预期结果 建议19:断言绝对不是鸡肋 建议20:不要只替换一个类 回到顶部 建议16:易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP,Ruby,Groovy.Javascript等,这些入侵者都有一个共同特征:全是同一类语言-----脚本语言,它们都是在运行期解释执行的.为什么Java这种强编译型语言会需要这些脚本语言呢?那是因为脚本语言的三大特征,如下所示:

编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议98~101)

建议98:建议的采用顺序是List<T>.List<?>.List<Object> List<T>.List<?>.List<Object>这三者都可以容纳所有的对象,但使用的顺序应该是首选List<T>,次之List<?>,最后选择List<Object>,原因如下: (1).List<T>是确定的某一个类型 List<T>表示的是List集合中的元素都为T类型,具体类型在

编写高质量代码:改善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); }