改善java程序的151个建议--枚举和注解

83、项目开发中,推荐使用枚举定义常量,来代替接口常量或类常量

Eg:enum{Spring,Summer,Autumn,Winter;}

枚举定义常量相对于经常使用的常量类和静态常量相比的优势:

1)枚举常量更简单:枚举常量不需要定义枚举值,int spring=1;枚举表示的 是一个枚举项,字面含义不同,其他常量必须是一个类型;

2)枚举常量属于稳态型

3)枚举具有内置的方法,例如values:获得所有值的集合,可用于遍历,ordinal: 获得排序值,compareTo比较方法等;

4)枚举可以自定义方法:枚举常量不仅可以定义静态方法,还可以定义非静 态方法,还能够从根本上杜绝常量类被实例化

缺点:枚举类型是不能有继承的,枚举常量定义完毕后,除非修改重构,否则无法做扩展。

枚举类型的遍历:

for(Season s:Season.values()){
			System.out.println(s);
}

84、使用构造函数协助描述枚举项

enum Season{
	//通过构造方法可以为枚举项添加描述和其他定义
	Spring("春","春暖花开"),Summer("夏","艳阳高照"),Autumn("秋","秋高气爽"),Winter("冬","雪花飘飘");

	private String desc;//描述
	private String other;//其他

	//添加上述描述和定义必须添加下面所示的构造方法
	Season(String desc,String other){
		this.desc=desc;
		this.other=other;
	}

	//获得描述
	public String getDesc(){
		return desc;
	}
	//获得其他
	public String getOther(){
		return other;
	}
}

推荐在枚举定义中为每个枚举项定义描述,比在接口常量或类常量中增加注释的方式友好、简洁

85、小心switch带来的空值异常

	public static void testSwitch(Season s){
		switch(s){
		case Spring:System.out.println("春");break;
		case Summer:System.out.println("夏");break;
		default:throw new AssertionError();
		}
	}

上面代码,如果做测试:testSwitch(null);会发现在switch(s)处抛出空指针异常,这是因为java能判断的switch类型为short、byte、int、char类型,那么为什么枚举类型能编译通过呢,这是因为编译器是根据枚举类型的排序值进行判断的:Switch(s.ordinal()){case Season.Spring.ordinal()},如果为null值,那么没有ordinal方法,肯定会抛空指针异常,所以解决方法是在该方法中加入是否为null判断

86、在switch的default代码块中增加AssertionError错误

Default:throw new AssertionError();

87、使用valueOf前必须进行校验

枚举类中提供valueOf方法,用于查找字符串值与该参数相等的枚举项,返回一个枚举类型的数据

	//测试valueOf方法,因为Season不存在SpringTime会抛出
	//IllegalArgumentException异常信息
	public static void testValueOf(){
		List<String> list=Arrays.asList("Spring","SpringTime");
		for(String s:list){
			Season season=Season.valueOf(s);
			if(season!=null){
				System.out.println(s);
			}else{
				System.out.println("该枚举类型不存在");
			}
		}
	}

解决方案:

1、在Season.valueOf方法中添加try....catch方法进行捕获

2、在枚举类中添加一个判断是否存在的方法,例如:contains方法,如果存在
该字符串信 息,则进行valueOf 转换为相应的枚举类型,不存在则不转换

88、用枚举实现工厂方法模式更简单

89、枚举项的数量限制在64个以内

Java提供的枚举集合,由于枚举类型的实例数量固定并且有限,相对来说其效率会比其他Set和Map要高:

EnumSet:其元素必须是某一枚举的枚举项

EnumMap:key值必须是某一枚举的枚举项

EnumSet存储枚举类型数据时候,当枚举数量小于等于64时,创建一个RegularEnumSet实例对象,大于64时则创建一个JunmboEnumSet实例对象

	public static void testEnumSet(){
		EnumSet<Season> set1=EnumSet.allOf(Season.class);
		EnumSet<Season> set2=EnumSet.allOf(Season.class);
		//枚举类型Season中小于或等于64个元素,则得到的结果为:class java.util.RegularEnumSet
		System.out.println(set1.getClass());
		//枚举类型Season中超过64个元素,则得到的结果为:class java.util.JumboEnumSet
		System.out.println(set2.getClass());
	}

因为EnumSet提供的实现类底层都是基本的数字类型操作,其性能肯定比其他的Set类型要好很多,特别是数量少于64的时候,速度飞快.

90、小心注解继承

元注解:@Inherited,表示一个注解是否可以自动被继承

91、枚举和注解结合使用威力更大

//定义角色级别,用户,管理员,超级管理员
enum RoleIdentify{
	User,Admin,SuperAdmin;
}

//定义访问权限注解类
@Retention(RetentionPolicy.RUNTIME)//元注解,表示该注解的保留级别
@Target(ElementType.TYPE)//元注解,表示该注解可以标注在什么地方
@Inherited//元注解,表示该注解会被自动继承
@interface Access{
	//定义访问级别,默认为管理员
	RoleIdentify level() default RoleIdentify.Admin;
}
//使用自己定义的注解
@Access(level=RoleIdentify.User)
class TestAnnatation{

}

public class AnnatationTest {
	public static void main(String[] args) {
		//测试
		TestAnnatation test=new TestAnnatation();
		Access access=test.getClass().getAnnotation(Access.class);
		System.out.println(access.level());//打印输出User
	}
}

92、主要@Override不同版本的区别

如下代码:

interface MyInterface{
	public void doSomething();
}
class MyImpl implements MyInterface{
	@Override
	public void doSomething() {

	}

	public void doTest(List<String> strList){

	}
}

上面代码在jdk1.6版本上编译没有任何问题,但是在jdk1.5版本上编译上面代码会出错误:The method doSomething of type MyImpl override a superclass...

原因是jdk1.5中的@Override是严格遵守覆写的定义:子类方法与父类方法必须具有相同的方法名称、输入参数、输出参数(允许子类缩小)、访问权限(允许子类扩大),父类必须是一个类,不能是一个接口,否则不能算是覆写。

所以,如果是jdk1.6版本的项目移植到jdk1.5版本上面,就需要删除实现接口方法上的@Override注解。

时间: 2024-08-27 10:47:23

改善java程序的151个建议--枚举和注解的相关文章

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

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

编写高质量代码改善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个建议(第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个建议——[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个建议(第6章:枚举和注解___建议88~92)

建议88:用枚举实现工厂方法模式更简洁 工厂方法模式(Factory Method Pattern)是" 创建对象的接口,让子类决定实例化哪一个类,并使一个类的实例化延迟到其它子类".工厂方法模式在我们的开发中经常会用到.下面以汽车制造为例,看看一般的工厂方法模式是如何实现的,代码如下: 1 //抽象产品 2 interface Car{ 3 4 } 5 //具体产品类 6 class FordCar implements Car{ 7 8 } 9 //具体产品类 10 class B

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

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

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