标签:
?
?
目 录
?
5.6.????getXxxx方法和setXxxx方法的使用????7
17.3.????java.lang.String????12
17.4.????java.util.Vector????13
?
?
本规范的目的在于编写出可靠的,一致的,便于理解的JAVA源代码,并且写出的代码容易被其他人阅读,所有的JAVA代码保持良好的一致性,容易在以后的阶段中进行维护和升级。同时,也是为了通过一定时间的实践,增加软件产品的投入产出量,以提高工作效率。
在JAVA代码中,所有的代码命名的总原则是:
在JAVA代码中,我们经常要使用代码注释的方式来帮助理解代码的含义。代码注释的一般原则主要有以下几个方面:
?
在JAVA代码中,经常使用三种类型的注释:文档型的注释,其一般格式是:以"/**"开头,以"*/"结尾; C语言类型的注释,它通常是以"/*"开头,以"*/"结尾;还有一种是通常用的单行注释的方法,即以"//"开头,对一个单行进行注释。下面以表格的方式,分别说明这三种方式在JAVA中如何更好的使用。
注释类型 | 使用方式 | 例程 |
文档型注释 | 文档型注释经常用在定义接口,类,成员方法,域的定义之前,并且这种注释可以被通过javadoc直接生成帮助文档。 | /** Customer- A customer is any person or …… @author S.W.Ambler */ public class Customer{} |
C风格型的注释 | 当要一次对多行代码进行注释,或者这些代码将不被执行,或者对这些行进行调试时,本注释是一种比较合适的注释方法。 | /* This code was commented .. ………… ……(the source code) */? |
单行注释 | 通常在成员方法内部注释商业逻辑,一小节代码,或者临时变量的声明。 | //Apply a 5% discount to all //invoices over $1000 as //defined by the ….. |
?
?
同时,为了编程人员所做的文档型注释,能更有效的生成HTML格式的帮助文件,将提供以下一些更多的内容:
标志 | 使用 | 目的 |
@author authorName? | 一般在类、接口定义之前的文档型注释里面使用。 | 一般是指明编写本接口或本类的作者,当然可以有多个,每一个作者用@author标明。 |
@deprecated? | 一般在类,成员方法定义之前的文档型注释里面使用。 | 它一般用于声明一个类或者一个成员方法被废弃,不再使用。 |
@exception name description? | 成员方法定义之前的文档型注释里面使用。 | 用于声明本成员方法将可能会抛出的异常。每一个异常用一个@exception标明。 |
@param name description? | 成员方法定义之前的文档型注释里面使用。 | 用于说明传递给该成员方法的参数,包括其类型和它的使用,每一个参数用@param标明。 |
@return description? | 成员方法定义之前的文档型注释里面使用。 | 用于说明本成员方法的返回值类型,如果可能,适当的描述其可能的返回值 |
@see ClassName? | 一般在类,接口,成员方法,域定义之前的文档型注释里面使用。 | 用于建立一个超文本链接到指定的类,接口。一般应该详细的描述其类名。 |
@see ClassName#member functionsName | 一般在类,接口,成员方法,域定义之前的文档型注释里面使用。 | 用于建立一个超文本链接到指定的成员方法。一般应详细描述类名。 |
@version text? | 一般在类,接口定义之前的文档型注释里使用。 | 用于指定相应的版本信息。 |
?
成员方法的命名应该采用全英文单词且是大小写混合的方式来进行。方法名的第一个单词均小写,其它单词的首字母大写。而且方法名中第一个单词最好是一个动词形式的。如:openAccount() , printMailingLabel() , save() , delete() 等。
通过这样的命名规范,很容易看出这个方法是干什么用的,它的目的是什么。尽管有时方法名会比较长,但它能很容易让其他人理解本方法的意图。
get方法,它一般返回一个属性值,一般应将get放在方法名中第一个单词的位置。而当它返回的是判断其结果是true或者false的时候,一般用"is"来取代"get"。例如:getFirstName() , getAccountNumber() , isPersistent() , isAtEnd() 等等。
通过这种命名规范,就可以很清楚的知道本方法是返回一个对象的属性或返回一个boolean值。
同样,对于set方法,它一般是用于设置对象的属性值,同样也将set放在方法名中的第一个单词的位置。如:setFirstName(String aName), setAtEnd(boolean isAtEnd), setPersistent(boolean isPersistent)等等。
?
构造方法一般是用来创建一个对象时要执行的初始化操作。构造方法必须具有与类名完全一致的名字,其大小写也必须完全一致。这种命名规范是由sun公司确定,且必须遵守。
?
每一个成员方法的前面必须要有相应的注释文档说明,它主要包括以下内容,但不仅限于以下内容:
?
为了更好的描述成员方法的目的,还会在成员方法的内部给予适当的注释,一般有两种格式:/*……..*/和//……….。一般而言,内部注释文档应该说明以下一些要素:
?
成员方法的访问权限控制的基本原则是尽量的限制对成员方法的访问权限。如果没有必要设置为public,则将其设置为protected,否则设置为默认方式或者private。
?
getXxxx方法和setXxxx方法的名称一般是: get + 属性名/ set + 属性名 或 is +属性名。 例如:
属性名 | 类型 | get方法 | set方法 |
FirstName? | String? | getFirstName()? | setFirstName(参数表) |
Persistent? | Boolean? | isPersistent()? | setPersistent(参数表) |
OrderItems? | Array of OrderItems Objects? | getOrderItems() | setOrderItems(参数表) |
getXxxx方法和setXxxx方法一般对其有如下的使用方式:
// Answer the branch number, which is the leftmost four digits of the full account number
protected int getBranchNumber(){
if (branchNumber = = 0){
//The default branch number is 1000,which is the main branch in downtown Bedrock
setBranchNumber(1000);
}
return branchNumber;
}
getXxxx方法和setXxxx方法的访问权限的控制:
一般情况,将它们设置为"protected",这样,只有同包类或子类的对象可以访问它们。但是通常将getXxxx方法设置为"public"方式,而setXxxx方法则是"protected"方式。只有在极少数情况下才将setXxxx方法设置为"public"方式。当然,有时也将setXxxx方法设置为"private"方式。
?
属性变量的命名采用全英文单词的混合命名方式,第一个单词全部小写,以后单词的
第一个字母大写,其余小写。以便让它易于理解。而对于那些像数组或动态数组等一些多值的数据类型属性,则应该采用单词复数的方式命名(s加在最后一个单词上面),它的主要优点是可以方便的指明它们有多个值。例如: firstName, zipCode, orderItems等。
?
为了使对象具有更好的封闭性,一般不把属性的访问权限设置为public,建议一般把所有的属性访问权限设置为private,以防止其它类的对象直接访问本类对象的属性。而对属性的访问可以用getXxxx方法和setXxxx方法进行。
?
每一个属性变量都要给予注释,以便其他开发人员更好的理解其含义。一般从以下几个方面给予注释:
?
对于组件的命名,一般采用全英文单词的命名方式,但是采用将组件类型名作为后缀的方法。这样,就很容易识别这个组件变量的目的,从它的后缀类型就可以方便的看出。也很容易在列表中找到每一个组件(在很多可视化编程环境中,提供列表的方式来快速显示所有用到的组件变量)。如: okJButton, fileJMenu, newFileMenuItem等等。
?
常量命名采用全英文单词的方式进行,且全是大写的字母,单词之间用下划线连接。如:MINIMUM_BALANCE, DEFAULT_START_DATE等等。 它的主要优点是可以很容易的与变量区分开来。
?
一般而言,局部变量的命名规范遵循属性变量的命名规范,即全用英文单词命名,且除第一个单词以外,其它单词的首字母均大写。
但是,对于下面所列举的几种特殊类型的局部变量的命名有些特殊的规定:
1.streams
当一个单一的输入或输出流对象被定义和使用时,一般用in,inputStream表示输入流,而用out,outputStream表示输出流。而当一个流同时被使用为输入流和输出流的时候,则用inOut或者ioStream来命名。
2.循环计数器的使用
由于在成员方法中,我们经常会用一些循环结构,同时也就会使用循环计数器。在以前的C,C++中,已经习惯于使用像i,j,k等变量作为循环计数器,在JAVA编码中,也采用常用的,单一的小写字母来命名循环计数器。例如:for(i=0;i<10;i++)
3.异常对象的命名规范
在JAVA中,经常会碰到一些例外情况的处理,一般用一个字母"e"来命名相应的例外对象,如存在多个异常则采用属性的命名方式。
?
局部变量的文档注释一般涉及到以下几个方面:
成员方法参数的命名规范基本上与局部变量的命名规范相同。 如: customer, inventoryItem, in , e等。
成员方法参数的文档注释:
成员方法参数的文档注释在成员方法的头部注释文档中,它应包括以下内容:
?
类的命名也是采用全英文单词描述的方法,但它的第一个单词的首字母必须大写,其它单词的首字母也要大写。例如: public class Customer{….} public class OrderItems{…}
?
类的注释文档一般位于类的定义之前,它将包含如下内容:
?
接口的命名,其第一个字母必须是大写的"I",以表明它是一个接口,与其它类进行区别。剩下的部分与类的命名规范一样,采用全英文单词描述的方法,第一个单词首字母大写,其它单词的首字母也大写。例如:public interface IOrderItems{……..}
public interface ICustomer{…..}
?
接口的文档注释必须在接口被定义前给予说明,主要包括以下内容:
3.接口内的抽象成员方法的注释,参照类的成员方法的注释。
?
包的命名有以下几个规则:
对于每一个包,应该有一个或多个外部文档来描述这个包。一般而言,文档中应描述如下内容:
?
程序应以缩进形式展现程序的块结构和控制结构,在不影响展示程序结构的前提下尽可能地减少缩进的层次。采用如下两种缩进方式之一:
1) |
if (expression ){ statements }else{ statements }? |
?
一个程序的宽度如果超出页宽或屏宽,这将是很难读的,所以本规范要求使用折行缩进的方法、合并表达式或编写子程序的方法来限制程序的宽度。
1)任何一个程序最大行宽不得超过80列,超过者应折行书写。
2)建议一个函数的缩进不得超过5级,超过者应将其子块写为子函数;
3)算法或程序本身的特性有特殊要求时,可以超过5级。
?
?
性能优化的原则是先让程序运行起来,再考虑变得更快——但只有在自己必须这样做、而且经证实在某部分代码中的确存在一个性能瓶颈的时候,才应进行优化。进行优化时需使用专门的工具分析瓶颈。需要注意的是性能提升的隐含代价是自己的代码变得难于理解,而且难于维护。
对于像字符串的连接操作不使用"+"而使用专有方法 concat等其他方法,这类问题,则不能称为性能优化,而只能叫做基本常识。这类问题的解决注意不能影响程序的可读性和易维护性,以下是常见优化常识:
?
详见表9-1运算时间。
表 9-1 运算时间
运算 | 示例 | 标准时间 |
本地赋值 | i=n; | 1.0? |
实例赋值 | this.i=n;? | 1.2? |
Int增值 | i++; | 1.5? |
Byte增值 | b++;? | 2.0? |
Short增值 | s++;? | 2.0? |
Float增值 | f++;? | 2.0? |
Double增值 | d++;? | 2.0? |
空循环 | while(true) n++;? | 2.0? |
三元表达式 | (x<0)?-x:x;? | 2.2? |
算术调用 | Math.abs(x);? | 2.5? |
数组赋值 | a[0]=n;? | 2.7? |
Long增值 | l++;? | 3.5? |
方法调用 | funct();? | 5.9? |
Throw 或者catch 违例 | Try{throw e;}? | 320? |
同步方法调用 | synchMethod(); | 570? |
新建对象 | new Object();? | 980? |
新建数组 | new int[10];? | 3100? |
?
字串的开销:字串连接运算符"+"看似简单,但实际需要消耗大量系统资源。编译器可高效地连接字串,但变量字串却要求可观的处理器时间。该操作要创建并拆除一个StringBuffer对象以及一个String对象。
上述问题的通常解决方法是新建一个StringBuffer(字串缓冲),用append方法追加自变量,然后用toString()将结果转换回一个字串。当要追加多个字串,则可考虑直接使用一个字串缓冲——特别是能在一个循环里重复利用它的时候。通过在每次循环里禁止新建一个字串缓冲,可节省980单位的对象创建时间(见表9-1)。
更有效的解决办法是:在构造 StringBuffer 时,应该粗略的估计出它最终的总长度。默认构造函数预设了16个字符的缓存容量。append()方法首先计算字符串追加完成后的总长度,如果这个总长度大于StringBuffer的存储能力,append()方法调用私有的expandCapacity()方法。expandCapacity()方法在每次被调用时使StringBuffer存储能力加倍,并把现有的字符数组内容复制到新的存储空间。存储能力的扩展,从而导致了两次代价昂贵的复制操作。因此,我们至少有一点可以做得比编译器更好,这就是分配一个初始存储容量大于或者等于最终字符长度StringBuffer。
因此,使用默认构造函数创建的StringBuffer在字符串连接操作上的效率其实和用"+"是一样的。如果首先估计出整个字符串最终的总长度,才会显著提高效率!
其他的字符串运算操作尽可能使用 String 已经提供的方法。比如,短字符串的连接可以使用 concat;子串的查找可以使用 indexOf,substring 等。
?
一个Vector就是一个java.lang.Object实例的数组。Vector与数组相似,它的元素可以通过整数形式的索引访问。但是,Vector类型的对象在创建之后,对象的大小能够根据元素的增加或者删除而扩展、缩小。
(1)避免把新元素添加到Vector 的最前面
(2)避免从中间删除元素
(3)删除所有元素的最好方法是 removeAllElements()
(4)避免二次搜索
Vector类型的对象v包含字符串"Hello"。考虑下面的代码,它要从这个Vector中删除"Hello"字符串:
String s = "Hello";
int i = v.indexOf(s);
if(i != -1)
v.remove(s);
在这段代码中,indexOf()方法对v进行顺序搜索寻找字符串"Hello",remove(s)方法也要进行同样的顺序搜索。改进之后的版本是:
String s = "Hello";
int i = v.indexOf(s);
if(i!= -1) v.remove(i);
这个版本中我们直接在remove()方法中给出待删除元素的精确索引位置,从而避免了第二次搜索。一个更好的版本是:
String s = "Hello";
v.remove(s);
循环内部的代码不会以任何方式修改Vector类型对象大小时,应该提前取得Vector.size()
不必要的同步常常会造成程序性能的下降。因此,如果程序是单线程,则一定不要使用同步。
对某个方法或函数进行同步比对整个代码段进行同步的性能要好。因为代码段的同步牵涉的范围比对某个方法或函数进行同步广。
一般每个对象都只有一个"锁",这就表明如果两个线程执行一个对象的两个不同的同步方法时,会发生"死锁"。即使这两个方法并不共享任何资源。为了避免这个问题,可以对一个对象实行"多锁"的机制。
?
循环的边界是指完成所有循环操作的起点和终点。如果循环体内的操作不影响边界,那么应该在循环体外,计算并且求得边界值。例如:
for(int i = 0; i < array.length; i++)
{
???? array[i]=i;
}
上述代码中每次循环操作,都要计算一次 array.length。
如果在循环体内用到新对象,需要在循环体开始以前构建好该对象。由标准时间表可以看出构建对象有很大的系统消耗,并且在一次循环中还要清除掉该对象,下循环再重新构建。
????????
遍历数组、集合时,如果满足条件的元素找到,一定要使用 break 语句退出循环。
?
标签:
原文地址:http://www.cnblogs.com/ustc-cui/p/4502801.html