java语言的特点:面向对象、简单化、解释型、平台无关、多线程、安全高效、动态性。
java的多线程机制使软件能并行执行同步机制,保证了对共享数据的正确操作。
java不允许使用指针或释放内存,从根本上避免了非法内存操作。
为适应web应用的快速变化的需求,java允许程序在运行中下载代码段并动态改变程序的状态。
java通过接口支持多重继承,使类的集成更具有扩展性。
java语言为实现其目标,使用了java虚拟机(JVM)、java运行环境(JRE)和垃圾回收机制。
java语言的执行模式是编译+解释,其程序的下载和执行步骤为:
(1)源程序首先由编译器转换为标准字节代码;
(2)浏览器与服务器连接,要求下载字节码文件;
(3)服务器将字节代码文件下载到客户机;
(4)然后由客户机上的JVM解释器执行代码;
(5)在浏览器上显示并交互。
JVM运行的代码存储在.class文件中,每个文件最多包含一个public类,且该类名与文件名相同。
每个java解释器都有一个JVM的具体实现来完成加载代码、校验代码、执行代码三项任务。
类加载器负责加载代码,字节码校验器负责校验代码,解释器负责执行代码。
java语言中的所有代码都封装在类中,需要时创建类对象/类实例来处理,这种动态实例存储在内存堆中。
java语言的运行平台包括java应用程序接口(API)和JVM。
java有Java SE、Java ME和Java EE三种平台,它们立足于java核心开发工具包(JDK)。
java有一个系统级线程,它自动跟踪内存的使用,在JVM空闲时,它可回收不用的内存。
这消除了释放内存的必要,也避免了内存的泄漏,将程序员从琐碎的内存管理中解脱出来。
人们用层次分类法管理抽象的事物,并根据物理意义将复杂的系统分解为若干个简单的小部件。
java是完全面向对象的编程语言,它强调按照抽象、分类、继承、组合、封装等原则模拟现实中的事物。
面向对象的基本概念:抽象、封装、继承、多态:
面向对象技术将现实问题抽象成许多的类来表示,然后把问题分解成许多标准接口的构件。
封装将程序中的对象的状态和行为形成一个完整的、结构高度集中的整体。
封装单元对外有明确的功能、接口单一通用,可在各种环境下独立运行,且对象的具体实现细节被隐蔽。
封装隔离了对象的设计者和使用者,其源代码不受外界干扰,可独立编写和维护,有利于代码复用。
继承是指一个新类(子类)包含另一个已有类(父类)的状态和行为。
子类的派生过程称为类的继承,继承是抽象分层管理的实现机制。
多态是指允许一个类中拥有多个具体实现细节和机制不同的同名方法。
类是具有相同特性对象的封装组合,类是java程序的基本单位,java编程就是编写类的过程。
类的声明:【类修饰符】class 类名【extends 父类名】【implements 接口名列表】{类体}
类修饰符有:
public
-公共类,使该类可被其他类访问或引用其成员变量和成员方法,含main()
方法的类必须是public类。
abstract
-抽象类,使该类不可实例化,定义它常常为改变它的子类而设置。
extends
用于声明该类从哪个父类派生,implements
用于声明该类所实现的接口。
final
-终类,使该类不可被继承。
无类修饰符时,该类默认只允许被同一包中的类访问和调用。
成员变量:【变量修饰符】类型 变量名【=初值】, 变量名【=初值】,……
变量修饰符有:
final
-使该变量成为不可被改变的常量。
public
-使该变量允许被所有的类访问。
protected
-使该变量仅允许被同一包中的类及其子类访问。
private
-使该变量仅允许在本类内部访问。
static
-使该变量可不用定义类对象而直接被访问,如Math.PI
。
访问a类的实例(或static变量)b的语句为a.b
。
成员方法:【方法修饰符】返回值类型 方法名(参数类型 参数, 参数类型, 参数,……){方法体}
传入方法的变量的数据类型和参数的数据类型不一致时,java会尽量自动转换。54
方法修饰符有:
public
、protected
、private
、static
与成员变量同理。
abstract
-抽象方法,没有定义方法体,且不能和static
、final
共用。
final
-终结方法,不允许子类方法覆盖它。
native
-表示是其它编程语言的方法,用它与java代码继承。
synchronized
-并行方法,表示多个并发线程对共享数据访问的控制。
this.对象
用于在类中有多个构造方法时解释引用变量与参数之间的模糊性,或作为参数传递给另一个方法。
super.对象
可以获取父类中的变量数据,调用父类中的构造方法。
java程序中的变量只能是是基本数据类型值或引用值,引用值是经类实例化后的对象。
对象只能是其他对象的组合,而不能包含其他对象,故对象只能被其他对象引用。
删除对象是由系统运行时管理。
对象的主要属性是状态和行为:计算机用变量表示对象的状态,用方法表示对象的行为。
具有相同属性的对象抽象为类:类是对象的抽象,而对象是类的实例。
在java中,对象只能通过引用来操作;创建对象时内存中的存储是该对象的一个句柄,即该引用值的堆地址和有关信息,并非直接的内存地址,也不是引用值本身。
一个对象允许有多个引用,这些引用称为对象的别名。
创建类a的对象b的语句是a b
。
程序在用new
关键字实例化一个对象后,才给对象分配内存,并调用对象的构造方法,返回该对象的引用。
java允许在创建实例变量时不赋初值,但要求在使用前必须赋初值。
给一个实例对象赋初值null
代表一个空地址,此值表示变量暂时还没引用任何对象,但有初始化。
如果对象变量是一个类变量,在创建时如果没用new
,则其默认初始值为null
,但实例变量没有默认的初值。
因此,a b1=null;a b2=b1
合法,但即使a b3;
合法,也会导致a b4=b3
不合法。
java中每个类的声明都要求用一种特殊方法来初始化对象,这个方法被称为该类的构造方法。
构造方法名要求与类名相同,且无返回值,只能通过new
自动调用。
构造案例:class Point{int x,y; Point(){x=0;y=0;} Point(int x,int y){this.x=x;this.y=y;}}
java的对象成员变量的生存空间和周期都是从生成开始,直到不再被引用为止。
对象的清除是指释放对象所占用的内存。
java语言有自动手机垃圾功能,会周期性地回收一些长期不用对象的内存。
java系统开始运行时会自动调用java.lang.Object.finalize()
释放内存,也可在程序中调用重写的finalize()
释放系统资源。
还可调用System.gc()
手动请求垃圾回收。
包/package是java对一组相关的类、接口和子包进行封装的机制,和库比较类似。
声明一个包的语句为package 包名;
,包名以小写字母开头。
如果编译单元没有包语句,编译器默认为该单元在主机当前目录下工作。
在使用包之前需要先用import 包.*
导入,如果只想导入其中某个类,就把星号换成类名。
如果包里还有子包,子包里还有子包,导入时则写作import 包.子包.子子包.*或类名
。
java中提供的基本类库Java API中的包有:
——核心的java包:
java.lang
包封装所有应用的基本类,如Object、Integer、Class等。
java.awt
包封装了抽象窗口工具,用于构建和管理用户图形界面功能。
java.applet
包用于执行Applet程序。
java.bean
包用于开发编写java bean。
java.io
包用于程序的输入输出操作。
java.net
包用于执行网络通信应用或处理URL。
java.rmi
包用于调用程序远程方法。
java.math
包用于数学计算。
java.util
包提供实用程序类和集合类。
java.sql
包用于访问和处理标准数据源数据。
java.security
包用于网络安全操作。
java.text
包用于处理文本、日期、数字以及非自然语言的消息操作。
——扩展的javax包:
javax.naming
包用于命名服务。
javax.swing
包用于构建和管理应用程序图形界面。
javax.rmi
包提供远程方法调用的应用程序接口。
javax.transaction
包用于处理事务。
javax.sound
包用于处理音频文件。
javax.accessibility
包与用户界面构建之间的相互访问机制有关。
——以及有关国际组织的标准的org包。
java程序的结构可以包含package...
、import...
、public class...
、class...
、interface...
。
java应用程序的编写和执行过程为:
用无格式文本编辑器编写源代码(无格式的是txt,有格式的是Word)→编译源代码→解释和执行。
java Applet程序的编写和执行过程为:
编写源代码→编写HTML文件调用该小程序→编译源代码→解释和执行。
Object是所有类的根,它所包含的属性和方法被所有类继承,所有的java类都从它派生出来。
java.lang.Objects类是java系统中所有其它类的终极父类。
——Object类中有6个方法可以被系统中的每个类继承:
public String toString()
用于获取用字符串表示的当前对象的信息,在使用时往往需要在类中重写该方法。
public boolean equals(Object obj)
用于比较两个对象是否是同一个对象,使用时也要重写。
public int hashCode()
用于获取对象的哈希值。
public final Class getClass
用于获取当前对象所属的类的信息。
protected Object clone()
用于复制对象。
protected void finalize() throws Throwable
用于声明回收当前对象所需释放的资源。
此外,用obj instanceof a
可以求obj
对象是否属于a
类。
Class类属于系统类,可以表示所有的java数据类型,也可以在任何数据类型的名称后面加.class
。
Class类包装了对象或接口运行时的状态和信息,每当编写并编译一个新类时,就会产生一个Class对象。
JVM在运行程序时会使用“类加载器”生成Class类对象,当某个类的Class对象被载入内存时,它就被用来创建这个类的所有对象。
Class类最大的用途是在程序执行期间帮助加载新的类。
java允许动态加载,所有类只有当第一次引用时才需要加载到系统中。
Class类没有构造方法或变量,而所有类中从Object继承来的getClass()
方法都会返回一个Class类的对象。
getMethod()
方法可以一个方法对象f,它可以用println
打印出来,也可以用f.invoke()
执行该方法。
Class类的newInstance()
方法创建了一个指定类的实例,它适用于目标类含有一个无参数的构造方法的类。
可以将含有包路径的类名传给静态方法Class.forName()
来动态装载类,类也可用ClassLoder
装载。
枚举类型(Enum)是一组已命名的数组常量,枚举常量是一些可自定含义的标识符。
枚举类型中是一对对“键-值”,有python的字典内味了。
定义枚举型量的格式为enum Dict{键1(值1),键2(值2)…};
,不过键得是标识符。
从枚举中按键索值的语句为Dict dict=Enum.valueOf(Dict.class,键)
。
抽象类/Abstract是一种不能被实例化的类,它使编写程序更贴近现实世界和人类的思维方式。
抽象类必须被继承,而其中的抽象方法只声明不实现,所以在子类中必须将这种方法覆盖为具体的方法。
抽象方法在定义时也要加abstract
。
子类继承父类时,在类首行写class 子类 extends 父类
。
有时为了阻止某个类生成对象,而这个类中的方法不全是抽象的,此时也可声明其为抽象类。
如果一个抽象类的子类没有实现其父类中的所有抽象方法,则该子类仍然是抽象的。
java的接口可实现多继承并简化其复杂性,接口是和类关联非常紧密的一种引用类型。
接口的声明格式为【接口修饰符】interface 接口名【extends 父类名】{各种方法原型或常量的声明}
。
无论类的层次如何,不同的类可以有相同的接口,接口只声明一组方法,但不实现它们。
接口默认只能被所声明的类使用。
在类的开头加上implements 接口名
以使用并实现该接口。
接口也可以作为一种引用类型使用,然后通过引用类型变量去访问类所实现接口中的方法。
当用一个类去实现接口时,该类必须实现该接口的所有方法和它的父接口。
内部类也叫嵌套类,它允许将一个类的声明嵌套入另一个类的声明中、
内部类的类名只能在它声明的类或程序段或在表达式中匿名使用,外部使用它时必须给出类的全名,而且内部类的类名不能与包含它的类名相同。
除static型内部类外,不能在类内声明static成员。
但是,若内部类声明为static,它就会变成顶层类,此时虽然不能再使用局部变量,但可以声明static成员。
内部类适合用于实现图形界面这种多个类使用相同接口的情形。
每个变量在使用之前必须有唯一数据类型的声明,不允许重复声明。
在赋值前,检查赋值运算符两端的数据类型是否一致,如不匹配的则被强制转换。
在调用方法时,传递函数及返回值的类型与方法声明的类型相同。
java标识符开头除了可以用英文字母和下划线,还可以用$
,后面可以跟小于0xC0
的所有unicode字符。
标识符的字符数没有限制,但区分大小写,也不能是关键字。
字节型量/byte也是整型量,顾名思义,它的大小为1字节,类似于C中的字符。
java中的短整型(short)还是2字节,但整型/int是4字节,而长整型/long则是8字节。
整型变量的默认值为0,默认的类型是int,且局部整型变量必须赋初始值。
两个非long整型相运算,表达式的结果也默认为int型。
整型/整0
或整0/整0
会报错。
给java中的单精度变量赋值时,常量后面必须加F/f,长整型和双精度实型可不用加L/l或D/d。
java中可以将浮点数用在求余运算中。
java的特殊浮点数有除0.所得的Float/Double.POSITIVE/NEGATIVE_INFINITY
和0.÷0.所得的Float/Double.NaN
,它们在输出时分别会显示为(-)Infinity
和NaN
。
布尔型/boolean的大小为1字节,取值为true
/false
,注意和python的True
/False
区分开。
if
、if-else if-else
、?-:
、switch-case
、while
、do-while
、for
语句中的条件必须为布尔类型表达式。
java中的逻辑表达式输出的是布尔量而不是整型量,与·或·非运算符也只能用于布尔量。
对同一类不同的两个对象s1,s2使用表达式s1==s2
,结果为false
。
如果需要比较同一类的两个对象的值是否相同,需要用s1.equals(s2)
方法。
java中有一种逻辑右移运算符>>>
,用它右移时,最高位无视符号位而强行补0。
new()
的优先级低于自增·自减,而高于乘·除·余。**
字符型/char由于用的不是ASCII码而是unicode码,因此长为2字节。
字符可以用unicode表示,其格式为\u00FF
,数值必须为4位16进制数。
java有专门的字符串类型——String。
java的复合数据类型包括数组、类/class、接口/interface。
java只能将字节少的数据类型自动转换为字节多的数据,反之则需用基于括号的强制类型转换。
如果a=new 类型(初值),b=a;
,则a和b将指向同一个堆地址,要让它们相互独立,应该两个都用new赋值。
在函数内对传入的变量进行改变不影响原变量,但可以改变传入的类对象的内容。
对象包装器(wrapper)类有Byte
、Short
、Integer
、Long
、Float
、Double
、Character
、Boolean
、Void
九种。
将包装器对象转换成相应类型的变量的方法为……比如用Double包装的对象,后面跟方法.doubleValue()
求值。
包装器.MIN_VALUE
/包装器.MAX_VALUE
可以求相应类型量可取的最大值或最小值,包装器.SIZE
则可求相应类型量所占存储的位数。
字符串不是java的基本数据类型,而java类库中提供了一种字符串数据类型——String。
java中可以像python那样用加号连接字符串,甚至将其它类型量自动转换成字符串再跟字符串相连。
注意,1+2+"3"+4+5
会变成"3345"
,因为先执行(1+2),而到后面又是用字符串从左到右加。
——java中String类的字符串操作方法有:
字符串.length()
用于求字符串的长度。
字符串.charAt(字符)
用于索引字符串中的字符。
字符串.indexOf(字符)
用于求字符的首个下标,字符串.lastIndexOf(字符)
则可求最后一个下标,找不到则返回-1
。
字符串.getChars(a,n,c[],b)
用于将字符串中从第[a]个字符开始的n个字符提取到字符数组c的c[b]及其后位。
字符串1.concat(字符串2)
用于将两个字符串相连。
字符串.replace(c1,c2)
用于将字符串里的字符c1换成c2。
字符串.substring(起始下标)
、字符串.substring(起始下标,子串长度)
用于获取字符串的子串。
字符串.toUpperCase()
/字符串.toLowerCase()
用于将字符串中的英文字母转换为大/小写。
字符串1.equals(字符串2)
用于比较两个字符串的内容是否相同。
java中StringBuffer类的字符串操作方法有length()
、charAt()
、getChars()
、capacity()
……、
因为StringBuffer类的字符串长度可变,所以可为它追加字符,或者在它中间插入字符。
在java中,数组也是对象,其类型为引用类型,且引用类型变量在声明后必须实例化才能对变量进行访问。
在java中,数组括号可以放在变量之前或之后,比如int a[];
等价于int[] a
。
对象数组的初始值为null。
对引用类型的数组初始化,需要先为每个数组分配引用空间,然后为每个数组元素分配空间并赋初值。
java中的数组下标不必是常量,像C语言那样就太屑。
java中的二维数组的每一行不必是长度相同的一维数组,这点倒又像python。
java中,定义数组时不能加初始长度,给数组赋114个0的方式为int x[]=new int[114]
。
java中,多维数组定义时必须行列全空,比如可以用int x[][]=new int[514][]
给多维数组赋初值。
单行注释为//注释
,多行注释为/*注释*/
,可生成帮助文档的注释为/**…*/
。
导入整个库的格式形如import java.math.*;
,但使用其中的类方法时则为Math.random()
。
在java中,如果给外层循环加了标签,可以用break 标签
或continue 标签
直接跳出/跳过一次外层循环。
java把goto 标签
功能删减了,因为太屑。
方法的重载是指在同一个类中定义多个名称相同但参数和功能不同的方法,java支持对任一方法重载,包括构造方法。
JVM能够自动根据传递给方法的参数个数、类型和顺序决定调用哪个重载方法。
重载对象的默认值是0或null。
如果某个子类中的方法与父类中的方法有重名,但参数和功能不同,是为覆盖也,它是一种比较复杂的多态。
当一个方法被定义为final
时,它被禁止覆盖;但如果定义为abstract
,因为是空头方法,那就必须得覆盖。
覆盖方法时,子类方法的可见性不能低于父类方法的可见性(可见性public>protected>private)。
异常是编程语言中的一种用来描述如何处理某种非预期情况的机制。
java中的所有异常对象都是Throwable类的两子类-Error类或Exception类的实例。
Error类包括动态连接失败、硬件设备和虚拟机出错等不可查的严重错误,它们由java本身来抛出和捕获。
Exception类异常需要程序员需要捕获、声明和抛出。
Exception类包含RuntimeException、IOException、AWTException等子类。
RuntimeException类包含ArithmeticException、IndexOutOfBoundsException、InterruptedException等子类。
IOException类包含FileNotFoundException和EOFException等子类。
异常对象从产生到传递给java系统的过程称为抛出异常。
当异常被某一方法生成,而该方法不知道如何处理它时,则需在声明中抛出异常(又叫声明异常),让异常对象从调用栈向后传递,直到有其它方法捕获它为止。
声明抛出异常的语句为throws 异常类型1,异常类型2,...
,也可以自定义异常类型,但必须是Exception的子类,格式为throw new 异常类型名(返回值)
。
java系统将异常对象交给调用方法处理的过程称为捕获异常/catch。
捕获异常的语句为:
try{正常语句} catch(异常类型1 异常1){处理1} catch(异常类型2 异常2){处理2} ... finally{最终处理}
。
catch到的异常类型中,子类在先,父类在后。
断言/assert有助于验证程序中的某个方法或某个编程小组紧密耦合方法的内部逻辑。
断言语句可以检查一个布尔表达式,当它为false时,认为程序运行出错,系统会给予警告甚至退出程序。
断言的格式为assert 布尔表达式【:详情表达式】
,若布尔表达式为false则抛出AssertionError,不要捕获它。
在断言为false时,若后面有详情表达式,则会计算其结果,并用它作为AssertionError类的构造函数的参数来创建该类的对象,并抛出该对象,使得断言失败时能获得更多的信息细节。
——断言的使用方式有:
内在不变式:若“表达式0”为false时一定代表出错,则assert 表达式0
。
控制流不变式:确信某种情况一定代表出错时,则跳转到assert false
。
后置条件和类不变式:在方法执行后用assert对变量值或关系进行假设和验证。
——断言语句的参数有:
-ea
/-da
:打开/关闭所有用户类的断言。
-ea:<类名>
/-da:<类名>
:打开/关闭某一类的断言,如果要打开/关闭多个类/包,就在后面再加冒号和类/包名。
-ea:<包名>
/-da:<包名>
:打开/关闭某一包的断言。
-ea...
/-da...
:打开/关闭缺省包的断言,或者叫无名包。
-ea:<类名>...
/-da:<类名>...
:打开/关闭某一包及其子包的断言。
将上述参数的-ea
/-da
改为-esa
/-dsa
:则代表打开/关闭系统类的断言。
——ClassLoader类中与断言相关的API如下所示:
setDefaultAssertionStatus
用于开启或关闭断言功能,clearAssertionStatus
则关闭断言功能。
setClassAssertionStatus
/setPackageAssertionStatus
用于开启或关闭某些类/包的断言功能。
AssertionError是Error的子类,而不是一种Exception,更强调了断言错误的不可恢复的含义。
在作为公共方法的参数检查,永远要求执行时不可断言,否则会在关闭断言时无法执行。
断言语句没有任何边界效应,所以不要用断言语句修改变量和方法的返回值。
流是输入输出设备的一种抽象表示,可分为输入流和输出流或字节流和字符流。
“流”可以看做是一种流动的数据缓冲区,数据从数据源串行传送至数据目的地。
字节流分为对象流、内存流、字节管道流(线程通信流)、字节过滤流、音频流、图像流、二进制文件流、随机文件流等。其中,对象流最为直接简捷,成为程序员的首选项。
java中,用于读取字节序列的对象为输入流/InputStream,用于写入字节序列的对象为输出流/OutputStream。
输入输出在计算机系统中起到采集数据和提供数据处理结果的双重作用,它是以CPU为中心,以网络或外部设备为输入输出的双向数据传输机制。
java的三个标准输入输出流为System.in
、System.out
、System.err
,它们可以通过java.lang.System
类成员访问。
字符输入流为Reader,字符输出流为Writer。
——Reader类的主要方法:
i.read()
用于从输入流中读入一个字符,若输入流结束则返回-1。
i.read(char[] cc)
最多从输入流读入cc.length个字符并存入s,返回实际读入的字符数。
i.read(char[] cc,int off,int n)
最多从输入流读入n个字符,并将它们从cc[off]依次存入,返回实际读入的字符数。
i.skip(long n)
用于在输入流中跳过最多n个字符,返回实际跳过的字符数。
i.markSupported()
用于判断当前是入流是否可做标记。
i.reset()
用于给当前输入流重做标记。
——InputStreamReader的主要方法:
i.getEncoding()
用于获取当前字符流的编码方式。
i.InputStreamReader(InputStream ii)
可基于字节流ii生成一个输入字符流对象。
i.close()
用于关闭输入流。
——Scanner类的主要方法:
i.nextint()
用于读入在下一个分隔符之前的字符串,并转化为int。
i.nextLine()
用于读入下一行字符串。
——抽象类Writer中的主要方法:
o.write(int x)
用于把x的二进制数的低16位写入输出流中。
o.write(char[] cc)
用于把数组cc[]的字符写入输出流,cc也可是String型。
o.write(char[] cc,int off, int n)
用于输出数组cc中从cc[off]开始的n个字符,cc也可是String型。
o.flush()
用于清空输出流,并将缓冲的字符全部写入输出流。
——PrintWriter的主要方法有:
o.println(输出量)
用一行来打印量,记住典中典之System.out.println(输出量)
!!!
如果是o.print(输出量)
则不分行,直接在后面打印。
o.close()
用于关闭打印流,关闭了就打不了辣。
字节输入流为DataInputStream,字节输出流为DataOutputStream。
——InputStream类的主要方法:
i.read(byte[] n)
从输入流中读取若干字节并存入b,i.read()
则只读入一个字节,输入流结束则返回-1。
i.read(byte[] b,int off,int n)
用于从输入流中读取最多n个字节,从b[off]开始存入。
i.available()
用于获取输入流中的可读字节数,i.skip(long n)
则最多跳过n个字节,返回实际跳过字节数。
i.close()
用于关闭输入流并释放相关资源。
——Output类的主要方法:
o.writeInt(...)
/o.writeDouble(...)
/o.writeChar()
用于向字节输出流中写入相应的量。
o.write(int x)
用于把x的二进制数的低8位写入输出流中。
o.write(byte[] b,int off, int n)
用于从b[off]开始的n个字节写入输出流中。
o.flush()
用于清空输出流,将缓冲的字节全部写入输出流中。
用路径-文件名创建文件对象的语句为File 路径-文件名=new File(args[0]);
。
用路径和文件名创建对象的语句为File 文件对象名=new File(文件路径.getPath,文件名[i]);
。
——与File类对象file的名称有关的方法:
file.getName()
用于获得不含路径的文件名。
file.getParent()
用于获得文件的上级目录名。
file.getParentFile()
用于获得父路径文件对象。
file.getPath()
用于获得文件的整个路径-文件名。
file.list()
用于获得一个包含了和file同一目录下的所有文件名的列表。
file.renameTo(newfile)
用于重命名文件,返回值为是否重命名成功。
file.getAbsolutePath()
和file.getCanonicalPath()
用于获得文件的绝对路径名。
——与目录操作有关的方法:
mkdir()
创建目录,mkdirs()
创建包含附目录的目录。
list()
返回当前目录下的文件,list(FilenameFilter filter)
返回当前目录下经过filter过滤的文件。
lidtRoots()
返回根目录结构。
——其它与文件有关的方法:
file.isFile()
测试是否是文件,file.exsits()
测试文件是否存在、
file.canRead()
/file.canWrite()
测试文件是否可读/可写。
file.isAbsolute()
测试是否为绝对路径名。
file.hashCode()
用于返回文件的哈希码。
file.setLastModified(long time)
设置文件最后修改时间。
file.setReadOnly()
设置文件为只读。
——随机文件流及其方法:
用RandomAccessFile a=new RandomAccessFile("b.txt","r")
建立随机文件对象,该类兼有输入输出功能,它同时实现了DataInput和DataOutput接口,而且直接继承了Object类。
a.length()
用于求随机文件的字节长度。
a.readInt()
/a.readDouble()
/a.readChar()
用于从随机文件中读取int/double/char型变量。
a.seek(long pos)
用于查找随机文件记录,a.skipBytes(int n)
用于在访问文件时跳过n个字节。
a.close()
则可关闭随机文件资源。
检索压缩文件时,zip文件作为FileInputStream对象的构造方法参数,而该对象又以ZipInputStream构造方法参数出现。
压缩输入项的方法是getNextEntry()
,Scanner阅读文本的方法是nextLine()
。
此外,还有对象流、过滤流、管道流等,还有可匹配正则表达式的Pattern类和匹配特定字符串模式的Matcher类。
从传输速度上看,内存映射流的速度最快,其次是缓冲流(过滤流的一种),最慢的是直接使用文件流。
I/O流还应用于HTML、电子邮件处理、文件关键字检索、查询网络数据库、加载数据库属性文件等方面。
I/O流和多线程、数据结构等技术可配合使用。
进程是由代码、数据、内核状态和一组寄存器组成,而线程是由表示程序运行状态的寄存器,如程序计数器、栈指针以及堆栈组成。
进程是程序的一次动态执行过程,在进程执行过程中可以产生多个线程,形成多个执行流。
线程不包含进程地址空间中的代码和数据,而是计算过程在某一时刻的状态。
系统在产生一个线程或在各个线程之间切换时,所占资源要比进程小得多。
线程也被称为轻型进程,它是一个内核级实体,进程结构的所有成分都在内核空间中,一个用户程序不能直接访问这些数据。
线程是一个用户级实体,其结构驻留在用户空间中,能够被普通的用户级方法直接访问。
线程是程序中的一个执行流,它由CPU运行程序的代码、操纵程序的数据所形成,是以CPU为主体的行为。
java中的线程模型包含三部分:虚拟CPU、CPU执行的代码和代码所操作的数据。
线程中的代码和数据相互独立,当两个线程执行同一个类的实例代码时,它们共享相同的代码。
当两个线程访问同一个对象时,它们共享相同的数据。
程序中的线程都是Thread类的实例,用户可创建该类的实例或声明,或创建其子类的实例来建立和控制线程。
新建的进程不会自动运行,必须靠手动调用start()
方法才运行。
java中的线程体由线程类的public void run()
方法声明,在run()
方法中定义线程的具体行为。
线程的构造方法一般是public Thread(【ThreadGroup tg】【Runnable r】【String s】)
。
比如有某个类a实现了run()方法,则可用Thread t=new Thread(new a())
创建新进程t。
若类a被声明为Thread的子类,也可用a t=new a()
创建新进程t。
其中,tg可指明该线程所述的线程组,r可提供线程体对象,s可指定线程的名称。
java的每个线程都属于某个线程组(ThreadGroup类),它使一组线程可以作为一个对象进行统一处理或维护。
任何实现Runnable接口的对象都可以作为Thread类构造方法中的r参数,而Thread类本身也实现了Runnable接口,所以可由两种方式实现run()
方法:
通过实现Runnable接口创建线程,以及通过继承Thread类创建线程。
用实现Runnable接口的方式创建线程更符合面向对象设计的思想,且便于继承其它类。
用继承Thread类的方式创建线程的优点则是程序代码简单,易于直接调用线程方法。
运行状态是线程占有CPU并实际运行的状态。
线程在调用sleep()
、join()
、wait()
方法、进行输入输出操作或使用synchronized
请求对象锁而不得时,将会被阻塞。
线程的优先级中,MAX_PRIORITY
代表最高级,通常为第10级;NORM_PRIORITY
代表普通优先级,一般为第5级;MIN_PRIORITY
代表最低级,一般为第1级。
一般情况下,主线程具有普通优先级,且新建的线程会继承其父类的优先级。
由于目前的计算器多数只有单个CPU,所以一个时刻只能运行一个线程,如何安排线程的运行顺序被称为线程的调度。
java的线程调度策略是一种基于优先级的抢先式调度,即先运行优先级高的线程,直到其终止运行或比它更高级的线程开始运行。
java系统中可以按优先级设置多个线程等待池,JVM先运行高优先级池中的线程,等该池空后再考虑低优先级池。同时,如果有更高优先级的线程可运行,则运行它。
——Thread类的基本线程控制方法有:
Thread类的静态方法currentThread()
用于返回当前线程的引用。
t.getPriority()
/t.setPriority(int n)
用于获取/设置进程的优先级。
t.sleep(int m【,int n】)
:用于使某一进程休眠m毫秒(+n纳秒),常用于暂停高级别线程,以使低级别进程运行。
t.yield()
将进程t放入可运行进程池,并使其它同级别进程先运行。
t.join()
使当前进程等待,直到t结束为止再将线程恢复到runnable状态,也可以像sleep()那样增加定时。
t.interrupt()
用于在t调用其它方法被阻塞时清除其中断状态,但是t将收到InterruptException异常。
t.suspend()
用于暂停线程的执行,t.resume()
用于恢复线程执行,不提倡使用这俩方法,可能会锁死进程。
t.isAlive()
用于测试线程是否被启动,t.stop()
用于强行终止线程,也不提倡强行中止线程,它将造成堆栈数据不一致。
在java中引入线程是为了支持多线程程序设计,虽然各线程中的语句执行顺序是确定的,但线程的相对执行顺序不定。
java中用对象锁来对多线程对共享数据的操作进行并发控制。
一个程序中单独的、并发的线程对同一个对象进行访问的代码段被称为临界区。
java中的临界区可以是一个语句块或是一个方法,并且用synchronized
关键字标识。
用synchronized(对象)
指定的对象会获得一个对象锁,它使得同一时刻只能有一个线程访问该对象。
对象锁在synchronized()
语句块执行完或语句块中出现异常时,将会被持有该对象的线程返还。
当持有锁的线程调用该对象的wait()
方法时,它会释放对象锁,而被放入对象的等待池中等待某事件发生。
访问共享数据的所有代码都应放入临界区,使用synchronized进行标识。
用synchronized保护的共享数据必须是私有的,即必须通过对象的方法访问这些数据。
如果一个方法的整个方法体都在synchronized中,可将该关键字直接放在声明中。
在一个java线程在持有对象锁时,它可以再次请求并获得该对象的锁,它被称之为对象锁的可重入性。
对象锁的可重入性可以避免单个线程因为自己已经持有的锁而产生死锁。
java中没有专门检测与避免死锁的机制,只能通过编程来避免死锁的发生。
系统中使用某类资源的线程一般被称为“消费者”,产生或释放同类资源的线程则被称为“生产者”。
生产者-消费者问题是关于线程交互与同步问题的一般模型。
——线程间交互的方法:
obj.wait()
用于将线程放入对象obj的等待池,并且该线程将释放obj的对象锁。
obj.notify()
用于将该对象的等待池中的一个线程移入锁定池,在锁定池中的线程将在对象锁解锁后运行。
obj.notifyAll()
用于将该对象的等待池中的所有线程全部移入锁定池。
——Thread类的其它方法:
t.getName()
/t.setName()
用于获取/修改线程的名称。
t.activeCount()
用于获取当前线程所在线程组中活动线程的个数。
t.getThreadGroup()
用于获取当前线程所属的线程组名。
t.setDaemon()
用于设置当前线程为Daemon线程,t.isDaemon()
测试线程是否为Daemon线程。
t.toString()
用于以字符串形式返回线程的名字、优先级、线程组等信息。
t.enumerate(Thread[] T)
用于把当前线程所在线程组中的活动线程复制到线程组T中,包括它们的子线程。
t.checkAccess()
用于确认当前线程是否允许修改线程。
java中有集合类型,它分为Collection和Tree两大类接口 吗OK,,就类似于python的list、set、dict。
Collection包含List和Set两子接口,Set按升序排列又可得到接口SortedSet,它扩展了Set的操作功能。
Map是一系列关键字与值的映射元素对,它不允许对象中有重复关键字,每个关键字最多映射一个值。
同理,也有按Map关键字升序排列的特殊接口——SortedMap。
Collection接口无直接实现类,它只声明了许多抽象方法,这些方法对其所有子接口都可响应。
Set接口的实现类为HashSet/LinkedHashSet;
List接口的实现类是ArrayList/LinkedList/Vector;
Map接口的实现类为HashMap/Hashtable/LinkedHashMap;
SortedSet接口的实现类是TreeSet,SortedMap接口的实现类为TreeMap。
定义一个集合的语句为Collection 集合名=new 相应的实现类();
。
——Collection接口的抽象方法有:
集合.size()
用于求集合元素的个数。
集合.isEmpty()
用于求集合是否为空,集合.contains(obj)
用于求集合是否包含某个对象。
集合.add(obj)/remove(obj)
用于为集合增加/删减对象。
集合.containsAll(Collection C)
用于求C是否为该集合的子集。
集合.addAll(Collection C)
/removeAll(Collection C)
用于将C中的全部元素加入该集合/从该集合中删减。
集合.retainAll(Collection C)
用于删减本集合中不属于C的元素。
集合.toArray(【Object c[]】)
用于将集合中的所有元素返回为一个Object[]数组(或全部存入数组c)。
集合.Iterator iterator()
用于返回一个实现迭代接口的对象。
迭代器的定义为Interator 迭代器名称=集合名称.iterator()
。
迭代器.hasNext()
用于判断集合是否有下一个对象,迭代器.next()
用于让迭代器在集合中取下一个对象。
HashSet不保证有序,如要求有序可用其子类LinkedHashSet实现。
——Set接口的构造方法:
HashSet(【Collection C】)
用于构造一个新的(含集合C的)空Set。
HashSet(int n,float factor)
用于构造一个新的初始容量为n(且加载因子为factor)的Set。
List是元素有序并可重复的集合,可用相应的下标来寻找元素,其下标从0开始。
——List接口的方法:
get(int n)
/set(int n)
用于获取/设置下标为n的元素。
add(int n,Object obj)
/remove(int n)
用于在下标n处添加/删除对象。
addAll(int n,Collection C)
用于在下标n处用迭代方法插入集合C,返回是否成功插入。
indexOf(Object obj)
/lastIndexOf(Object obj)
用于求某一元素的首/末下标。
ListIterator listiterator(【int n】)
用于按一定顺序(从下标n开始)返回List中元素的列表迭代器。
Map的映射要求关键字唯一且有对应值。
——Map接口的方法:
m.get(Object key)
用于获取键对应的值。
m.put(Object key,Object Value)
用于向映射中插入键值对,m.remove(Object key)
用于按键削除键值对。
m.containsKey(Object key)
/containsValue(Object value)
用于判断映射中有无相应的键/值。
m.size()
用于求映射中元素的个数,m.isEmpty()
用于求映射是否为空集。
m.keySet()
/m.values()
用于获取映射中键/值组成的集合,m.entrySet()
则把映射中的所有条目转换为Set。
m0.putAll(Map m1)
用于将m1中的所有条目复制到m0中。
m.clear()
用于清除映射中的所有条目。
Vector实现动态数组,与ArrayList不同的是它是同步的,且包含许多不属于集合框架的方法,类似于隔壁的tuple,但不是只读。
——Vector类的方法:
Vector(【int n【,int inc】】)
默认创建一个10维向量,也可指定其容量为n,可指定其增量为inc,即向量每次允许向上改变大小的元素的个数。
addElement(Object obj)
用于在向量末尾增加元素,add(int n,Object obj)
用于在下标n处增加元素。
elementAt(n)
用于求下标n处的元素,insertElementAt(Object obj,int n)
和上面的add差不多。
capacity()
用于求向量的容量,size()
用于求向量中的元素个数。
还有以对象为元素的对象数组。
HashTable是无序的“散列表”,它和HashMap一样以关键字-值的方式存储元素,且通过索引访问对象。
——HashTable是字典这一抽象类的子类,它的方法有:
HashTable(【int n,【float fillratio】】)
用于创建散表,可指定其大小,还可指定其“填充比”,它默认为0.75。
当散表中的元素个数与其大小之比超过其填充比时,散表将被扩展。
HashTable(Map m)
用于以映射m中的元素初始化散表。
size()
用于求元素个数,isEmpty()
用于求表是否为空。
get(Object key)
用于按键索值,put(Object key,Object value)
用于添加键值对。
clone()
用于返回复制的对象,clear()
用于复位并清空散表,isEmpty()
用于求散列表是否为空。
containsKey(Object key)
用于求散表中是否有某键,contains(Object value)
或containsValue(Object value)
用于求散表中是否有某值。
Enumeration keys()
/Enumeration elements()
用于将散列表中的各键/值转化为枚举对象。
泛型是一种允许各个元素类型不同的集合。
泛型的的特点是:其主要目标是保障java程序的类型安全性,能消除代码中的强制类型转换,且较大地优化了JVM的性能,而且其实现时采用了“擦除”的方式。
泛型的定义形式为class O
,其中的A、B、C不代表值,而是表示类类型(包括自定义类),且不能是基本类型。
因为参数的不确定性,同一种泛型可以对应多个版本,但不同版本的泛型类实例互不兼容。
泛型的参数类型可以使用extends语句,如class A
,但这不代表继承,而是一种类型范围的限制。
不同类型的泛型类是等价的,即使a instanceof Pair==true
为真,也不代表a.getFirst()
的返回值是String类型。
泛型类不可继承Exception类,不可定义泛型数组,也不可用其创建对象。
在static方法中不可使用泛型,泛型变量也不可用static修饰。
不可在泛型类中定义equals()
这类方法,因为Object类也有该方法,当泛型类被擦除后这两个方法会冲突。
从同一泛型类衍生出来的多个类之间没有任何关系,也不可相互赋值。
若某个泛型类还有同名的非泛型类,不可混合使用。
抽象窗口工具包(Abstract Window Toolkit)是java提供的建立图形用户界面GUI的开发包,AWT可用于java的applet和应用程序中。
java.awt包提供了GUI设计所使用的类和接口,且主要有组件、容器和布局管理器三个概念,每个概念对应一个类。
组件/Component是一个可与用户交互的图形化对象,但它必须要放在容器/Container里才能显示出来。
容器是组件的子类,Panel、Frame、Applet、Window等则是容器的子类。
java.awt.Component是许多组件类的父类,一般编程过程中使用Component类的子类。
编写的图形界面的位置和大小是由布局管理器接口/LayoutManager决定的,编程时通常使用实现了该接口的类。
如果想用java语言提供的setLocation()
、setSize()
、setBounds()
等方法设置组件属性,则应用setLayout(null);
语句取消该容器的布局管理器,否则用这三种方法设置的属性都会被布局管理器覆盖。
Container的子类中,常用的子类又有Panel/面板、Frame/窗口、Applet等。
——Component类的重要成员方法:
c.getComponent(int x,int y)
用于获取坐标(x,y)处的组件对象。
c.getName()
用于获取组件的名字,c.getSize()
用于获取组件的大小。
c.getFont()
用于获取组件的字体,c.getForeground()
用于获取组建的前景色。
c.paint(Graphics g)
用于绘制组件,c.repaint()
用于重绘组件,c.update()
用于刷新组件。
c.setName(String x)
用于设置组件名称,c.setSize(Dimension d)
用于设置组件大小。
c.setvisible(Boolean x)
用于设置组件是否可见。
Frame是可以有标题、边框、菜单等元素的窗口,但该类对象实例化后必须先手动设置Size和Visible。
——Frame类的使用方法:
import java.awt.*;//导入awt库
public class File extends Frame{//File为源代码文件名,窗口类需继承Frame
public File(String str){super(str);}//继承父类的窗口构造方法,参数为窗口标题
public static void main(String args[]){
File frame0 = new File("Title");
frame0.setSize(114,514);//设置窗口大小
frame0.setBackground(Color.black);//设置窗口底色,妹说就是白色
frame0.setVisible(true);//设置窗口为可见,妹说就看不着
}
}
Panel是一种透明的容器,也叫面板,但它不能作为最外层的容器单独存在,所以必须作为一个组件放在窗口等其它容器中。
LayoutManager负责对容器内的组件进行大小、位置、排列顺序的管理,不同的布局管理器有不同的算法和策略,与之相关的类有FlowLayout、BorderLayout、GridLayout、CardLayout、GridBagLayout等。
FlowLayout按顺序排列组件,BorderLayout按区块排列组件,GridLayout以网格状排列组件,CardLayout一层层排列组件。
FlowLayout是Panel和Applet的默认布局管理器.
BorderLayout是Window、Frame和Dialog的默认布局管理器,且用East/West/North/South/Center表示方位。
在复杂的图形用户界面设计中,一个包含了多个组件的容器本身也可以作为一个组件加到另一个容器中,形成容器的嵌套。
AWT处理事件时主要涉及三类对象——
Event:用户对界面的操作在java语言中以类的形式出现,例如键盘操作对应的事件为KeyEvent类。
EventSource:事件源,它是事件发生的场所,通常就是各个组件,例如按钮Button。
EventHandler:事件处理者,该对象接收事件对象并对其进行处理。
一个事件处理者类需要实现与×××Event事件对应的接口×××Listener,才能处理相应类型的事件。
事件源实例化以后必须进行授权,并使用add×××Listener(×××Listener)
方法来注册监听器。
EventObject类继承与java.lang.Object类,并实现了串行化接口,通过getSource()方法可获得事件的源对象。
与AWT有关的所有事件类都由java.lang.AWTEvent派生,它也是EventObject的子类。
这些AWT事件可分为两大类:基于组件和容器的低级事件类和基于语义的,可不和特定动作相关联,而依赖于触发此事件的高级事件类。
——低级事件包括:
组件事件ComponentEvent,如组件的移动、组件尺寸的变化;
容器事件ContainerEvent,如组件的增加和移动;
窗口事件WindowEvent,如闭合、关闭窗口或将窗口图标化;
焦点事件FocusEvent,如焦点的获得和丢失。
以及键盘事件KeyEvent和鼠标事件MouseEvent等。
——高级事件包括:
动作事件ActionEvent,如按下按钮和在TextField中按Enter键;
调节事件AdjustmentEvent,如在滚动条上移动滑块以调节数值;
项目事件ItemEvent,如选择项目、不选择“项目改变” ;
文本文件TextEvent,如文本对象的改变。
——注册/注销监听器的方法:add/remove×××Listener(×××Listener listener0);
——键盘事件监听器的方法:
当敲下按键时,将执行KeyListener0.keyPressed(KeyEvent ev)
方法。
当抬起按键时,将执行KeyListener0.keyReleased(KeyEvent ev)
方法。
当敲击一次按键时,将执行KeyListener0.keyTyped(KeyEvent ev)
方法。
鼠标事件的方法有m.getX()
、m.getY()
……
java为一些Listener接口提供了适配器类(×××Adapter),可以通过继承事件对应的适配器类重写所需的方法,而不用实现不相关的事件。
事件适配器提供了一种简单的实现监听器的手段,以缩短程序代码,但由于java的单一继承机制,当需要多种监听器或者此类已经有父类时,就无法采用事件适配器了。
当一个内部类的声明只在创建此类对象时用了一次,而且要产生的新类需继承一个已有的父类或实现一个接口,才能考虑用匿名类。
匿名类无构造方法,它需要显式地调用一个无参的父类构造方法,并重写父类的方法。
Swing与AWT最大的区别是它是纯java实现的轻量级组件,无本地代码,不依赖操作系统的支持。
Swing是AWT的扩展,它提供了许多新的图形界面组件。
Swing的组件以J开头,除了有与AWT类似的JButton/JLabel/JCheckBox/JMenu等基本组件外,还增加了一个丰富的高层组件集合,如表格(JTable)和树(JTree)。
与AWT不同的是,Swing组件不能直接添加到顶层容器中,而是要添加到一个与顶层容器相关联的内容面板/ContentPane上。
•用Swing编写图形用户界面的特点
•Swing的事件处理机制
——Swing的组件:
JScrollPane:滚动窗口
JSplitPane:分隔板
JTabbedPane:选项板
JInternalFrame:内部框架
JButton:按钮
JRadioButton:单选框
JCheckBox:复选框
JComboBox:下拉选择框
JFileChooser:文件选择器
JLabel:标签
JList:列表
JProgressBar:进度条
JSlider:滑动条
JMenu:菜单
JTable:表格
JTree:数据树
JOptionPane:对话框
•Applet类的API 基本知识
•Applet编写步骤及特点
•基于AWT和Applet编写用户界面
•Applet的多媒体支持和通信
Java SDK的全称为Java SE Development Kit,也叫JDK,是原来Sun公司发布的,即今甲骨文公司。
一般情况下,JDK中需要安装的构件有开发工具、演示程序及案例和源代码。
JDK中,开发工具是java的核心,包括开发java程序必需的类库和工具,开发工具中已经包含了java运行环境JRE,因此不需再安装公共的JRE。
JDK演示程序和案例可供初学者入门java,源代码中则包含了java所有核心类库的源代码。
JDK的安装目录下会有以下文件(夹):
bin
用于存放JDK的各种工具命令,如java、javac等。
db
为Java DB的安装路径,如果没有选择安装它,则该文件夹为空
jre
用于存放java程序所必需的运行环境JRE。
lib
用于存放JDK工具命令的实际执行程序。
sample
用于存放JDK提供的简单示例代码,demo
用于存放JDK提供的演示程序。
src.zip
用于存放java所有核心类库的源代码。
——java的基本命令行命令:
javac【参数】源文件名
是java语言的编译器。参数中:
-classpath x
可定义javac搜索类的路径,它将覆盖默认的CLASSPATH环境变量的设置,一般格式为.;路径1;路径2;...
。
-d 路径
可指定便宜生成的类所存放的根目录。
java【选项】class【参数】
是java语言的解释器,可解释运行java字节码,其参数可用-classpath x
,含义同上。
javadoc
用于解析java源文件中类的声明和文档注释,并产生相应的HTML格式的文档。
appletviewer
用于使Applet脱离Web浏览器环境运行和调试。
jar
用于将多个文件压缩为基于ZIP和ZLIB的单个.jar归档文件。
jdb
是加多宝公司开发的 java程序调试器。
javah
用于从java类生成C头文件、C源文件和Stub文件。
javap
是java类文件解析器,用于解析类文件,若无使用选项则输出类的public域及其方法、
extcheck
用于检测目标jar文件与当前已安装的扩展(Extensions)之间的标题和版本冲突。
——java的RMI命令:
rmic
用于为远程对象生成stub和skeleton。
rmiregistry
用于在当前主机的指定端口上启动远程对象注册服务程序。
rmid
用于激活系统守候进程,以便能够在java虚拟机上注册和激活对象。
serialver
用于返回serialVersionUID。
——java国际化命令:
只有native2ascii
,用于将本地的非Latin-1
或unicode
字符编码文件转换为unicode
字符编码文件。
——安全控制命令:
keytool
用于管理密钥库和证书。
jarsigner
用于为java归档文件(.jar)签名,并可校验已签名的.jar文件的签名。
policytool
是用于管理策略文件的图形化工具。
kinit
是用于获得Kerberos v5 tickets的工具。
klist
用于列出证书缓存区和密钥表中的项。
ktab
是用于帮助用户管理密钥表的工具。
——java IDL和RMI-IIOP命令:
tnameserv
用于访问CORBA命名服务。
idlj
用于将用OMG IDL定义的接口文件翻译为.java文件,使java语言编写的程序能够使用CORBA功能。
orbd
用于支持client透明地定位和激活CORBA环境中的永久服务对象。
servertool
用于注册、撤销注册、启动或停止一个服务对象。
——没啥用但要考的Java编程规范:
总的原则是遵守命名规则,为代码写注释和文档,为代码分段且适当使用空白行,遵循第32条规则(方法别太长)。
尽量用相关英文单词,憋用拼音命名标识符。
标识符尽量不要太长,尽量避免使用拼写相似的名字。
变量名和方法名尽量不要以_
或$
开头,单词尽量用小写,每个小写词之间用首字母大写的形式隔开。
接口名、类名首单词大写,常量则全部大写,此时单词之间用_
分隔。
异常通常命名为Exception e
,循环计数器通常命名为i、j、k、counter等。
最好能让人一看到方法名就知道其功能,看方法名看30秒看不出功能的方法不好,也称“30秒原则”。
方法名宜用动词开头,比如获取用get,设置用set。
成员方法不宜太长,方法体最好能在一个屏幕内显示,也称“第32条原则”。
构件(Component)使用完整的英文描述说明其用途。
用/**.../
构造文档注释时,在说明类时,作者前加@author,版本前加@version;在说明方法时,参数后加@param,返回值后加@return,抛出异常后加@exception;一般的相关内容说明前加@see。
版权信息必须加在源文件开头,当然源文件开头还可以写一些不需要加入javadoc中的信息。
一个类的定义分为类的注释、类的声明和类体的定义。
源程序中应采用统一的缩进符,不推荐用\t
是因为不同的源代码管理工具中用户设置的\t
对应的字符宽度可能不同。
源文件页宽应设置为80字符,很长的语句应该在一个逗号或者一个操作符后折行,折行后还得缩进。
小括号和它内部的字符之间不应有空格。
以在代码中加入一些空行,把它分割为小的、易读的段落,可大大增加代码的可读性。
面向对象设计的基本原则之一是尽量减少类中的public和protected型接口,公共接口越短,类就越好理解,类的耦合性就越小,封装性也就越好,因此也就有更大的适应性。
为了提高程序性能,尽量不要在循环中创建或释放对象,且在处理字符串时尽量用StringBuffer类。
为了减少发生死锁的概率,应避免不必要地使用关键字synchronized。