Skip to main content

Java Basic Notes

CLI Tools

编译

javac name.java

运行

java name(无后缀类名)

反汇编

javap –c name(无后缀类名)

打包

jar {c t x u f} [v m e 0 M i][-c 目录] 文件名

解释:

  • c:创建 jar 包
  • t:显示 jar 包内容
  • x:解压 jar 包
  • u:添加文件到 jar 包
  • f:命名 jar 包
  • v:显示详细执行过程报告
  • m:指定 manifest.mf 文件(对 jar 包做相关设置)
  • 0:打包 jar 包是不压缩
  • M:不产生 manifest.mf 文件,覆盖 m 参数的设置
  • i:创建索引文件
  • C:进入某目录后再执行 jar 命令
  • 生成 API 文档:java doc –d [ ] 类名/包名

可选参数:

  • -author/-version:文档中显示作者和版本信息(默认不显示)
  • -link superlink 标准类名:为标准类添加超链接
  • -linksourse:方法/类名转化为超链接,指向生成的 html 格式的源文件

Gradle Tool

sudo apt install gradle

gradle help
gradle tasks

gradle assemble
gradle build
gradle clean
gradle test
gradle jar
gradle javadoc

Build Gradle

apply plugin: 'java'

jar {
manifest {
attributes 'Main-Class': 'com.sabertazimi.tao.Tao'
}
}

基本结构

数据类型

整型

类型
  • byte 型:1 字节 -128~127
  • short 型:2 字节 -2^15~2^15 -1
  • int 型:4 字节 -2^31~2^31 -1(20 亿)
  • long 型:8 字节 -2^63~2^63 -1
前/后缀
  • 二进制前缀 0b/0B
  • 八进制前缀 0
  • 十六进制前缀 0x/0X
  • 长整型后缀 l/L

浮点型

float 型

后缀 F:4 字节 -3403E383.403E38(有效位数 67 位)

float f = 1.2;    //ERROR
float f = 1.2F; //OK
double 型

后缀 D(默认型):8 字节 -1798E308~1.798E308(有效位数 15 位)

科学计数法:指数均为十进制,符号为 e(尾数为十进制)/p(尾数为十六进制)

Double.POSITIVE_INFINITY,Double.NEGATIVE_INFINITY,Double.isNaN(检数)

千分位下划线分隔法 e.g 123_456.789_000

字符型

  • 1 个 char 型占 2 个字节(Unicode 编码)

  • ’ ’(定界符)内可用八/十六进制转义字符表示字符

  • 八:\xxx

  • 十六:\uxxxx(\u 转义序列可出现在任何地方) e.g ‘\u0061’

改进的 Unicode 字符集:

  • 代码点(前缀 U+)分为 17 个代码级别(code plane)
  • 第一个级别为经典 Unicode 代码,
  • 其余附加级别 U+10000 至 U+10FFFF。

布尔型

只允许赋值为 true、false(不可取 0 或非 0 值),不可与整型相互转换

引用类型

数组(Array)

字符串 String:不可变性(需要修改变量名所引用值,必须重新创建一个 String 对象例)

旧的对象实例若被判定为垃圾便会被系统自动回收

类(Class)
接口(Interface)

常量

定义(随使用随定义)

运算符

短路与、短路或

  • &&:第一个操作数为假不再向后运算
  • ||:第一个操作数为真不再向后运算

移位符

有符号右移>>:最高位补符号位 左操作数 int/long,右操作数 mod32/mod64

e.g int a >> 33 即 int a >> 1

无符号右移>>>:最高位补 0

字符串连接运算符

+: 左右操作数 String 字符串/其他类型(自动被转化为 String)

判断运算符

==:

  • 基本类型值相等,引用类型引用相等
  • 基本类型:转换后比较;boolean 型不与 int 型比较
  • 引用类型:指向两个不同对象实例的变量不相等;若判断两个对象实例内容是否相等,必须调用 equals()方法

强制类型转换运算符

()

  • 只能在继承层次内进行强制类型转换(同一家族)
  • 将父类转换为子类前,应使用 instanceof 运算符进行检查

字符串

子串

stringTest.substring(a, b)方法返回长度为 b-a 的子串,a(包括)、b(不包括)为起止位置

相等

  • 内容相等:stringOne.equals(stringTwo)方法返回值 true/false
  • 不区分大小写 equalsIgnoreCase

常用方法

构建字符串

StringBuilder 类:单线程,功能同 StringBuffer 类(多线程)

输入输出

Scanner 类

监视器,功能最强大的输入类,new Scanner(System.in)

格式化输出方法

System.out.printf(): 静态创建格式化字符串

文件的输入与输出

输入(至内存)

用 File 对象构造一个 Scanner 对象:new Scanner(Paths.get(“FileName”))(反斜杠需双写)

输出(至文件)

用文件名构造一个 PrintWriter 对象: new PrintWriter(“FileName”), 之后调用System.PrintWriter.print方法.

表达式

  • 整数提升:算术运算前 byte,short,char 提升为 int
  • 没有”,”运算符和表达式语句

控制流程

合法语句:赋值语句和方法调用语句

块作用域

  • 不允许内层块与外层块变量同名(无 C 语言中的可见性)
  • 块内声明变量不允许在块外使用:if 块、for 块、while 块、普通 block

switch 语句

case 标签变量类型:字符型(包装类)、三整型(包装类)、枚举常量、字符串类

loop 语句

循环五要素
  • 初始化部分(init_statement);
  • 循环条件部分(test_explanation);
  • 循环体部分(body_statement);
  • 迭代部分(alter_statement):自加/自减运算符改变条件变量
  • 结束后处理
for each 循环
//只读遍历;变量age只作用于for循环体
for (int age : arrayName) {}

Break and Continue Statement

Break Statement
label:
{
break label;
} //可跳出任意语句块:跳至标签块末尾
Continue Statement
  label:
{
continue label;
} //跳至循环块首部

大数值

  • java.math.BigInteger
  • java.math.BigDecimal

数组

定义与引用

  • 类型(包括类/对象) + [] + 标识符.
  • 类型(包括类/对象) + 标识符 + [].
  • int a[N] 非法 数组是引用类型.
  • 不可对数组名进行自增操作(尽管 []* 具有类似作用).

初始化

  • 默认初始化数值类型为 0/false, 引用类型为 null.
  • 使用 new 分配内存单元.

两种不同初始化方式:

  • 声明时:MyDate[] dates = {new MyDate(),……};
  • 赋值时:MyDate[] dates = new MyDate[] (匿名数组){new MyDate(),…..};

方法

  • 属性:arrayName.length
  • 打印:arrays.toString 方法
  • 复制:arrayName.Copy( source, 0, destination, 0, source.length);
Arrays.copyOf(ArrayName, Array.length); //可用来增长数组长度
  • 比较:Arrays.equals(type[] a,type[] b);

命令行参数

字符串数组 String[] args, args 数组不包括程序名.

排序

Arrays.sort(ArrayName)快速排序方法

多维数组

  • 多维数组的声明和初始化应按从高维到低维的顺序进行:
    • 声明与初始化: int[][] t = new int[3][];.
    • 子数组交换: temp = a[i];a[i]=a[i+1];a[i+1]=temp;.
  • 子数组长度可不一致: 可先构造一维长度, 再使用循环构造子数组各自长度.

对象与类

面向对象的三大特征

封装性

  • 模块化 + 信息隐蔽: 隐藏细节 (private), 只提供受保护的访问接口 (public).
  • 只可通过方法改变对象实例的状态 (State/Instance Field).

继承性

父类和子类共享数据和方法 (提高代码重用率和可维护性):

  • 可继承成员: 公有域, 公有方法.
  • 不可继承成员: 私有域, 静态域, 实例域初始化块, 私有方法, 静态方法, 构造器方法.

多态性

不同的对象收到同一个消息 (method 调用) 可产生不同效果 (由对象内封装的细节决定):

  • 编译时多态:重载 (Overload).
  • 运行时多态:覆盖 (Override).
  • 根据对象实例的类型进行动态绑定 (Dynamic Binding).
  • 虚方法调用 (Virtual Method Invoking):
    • 在调用方法时,程序会正确地调用子类对象的方法.
    • 无法进行虚方法调用情况.
  • static 方法: 以声明类型 (标识符前的类型) 为准, 无关实例类型.
  • final/private 方法: 子类无法覆盖/继承父类同名方法, 不存在虚化问题.

完整的 Java 源文件

package packageName;              //指定文件中的类所在的包,0个或1个
import packageName.[className|*]; //指定引入的类/API,0个或多个
public classDefinition //属性为public的类定义,0个或1个
interfaceDefinition and classDefinition //接口或类定义,0个或多个

Behavior State and Identity

预定义类

Constructor

Georgia Calendar

用户自定义类

完整的类定义

[public] [abstract|final] class className[extends superclassName]
[implements interfaceNameList] {

//成员变量声明,可为多个:
//实例域一般添加private修饰符,保持封装性
[public | protected | private] [static] [final] [transient] [volatile]type variableName;

//方法(包括构造方法)定义及实现,可为多个
[public | protected | private] [static] [final | abstract] [native] [synchronized]
returnType methodName( [paramList] ) [throws exceptionList]{
statements;
}
}

class Class_Name{
int/String characteristic; //状态(State):变量(实例域 instance field)
constructor(){}; //标识(Identity):构造器(constructor)
void function(){}; //行为(Behavior):函数(方法method)
}

访问器方法(Accessor Method)

只访问实例域不进行修改的方法

returnType get() {
//保持封装性
//返回引用类型对象时,必须返回克隆体对象引用而不是实例域对象引用
return instanceFieldVariable.clone();
}

更改器方法(Mutator Method)

修改实例域的方法

e.g add、set

方法 Method

方法参数

Java 所有普通方法的参数传递方式:值传递

  • 基本类型:传递值的拷贝

方法中无法更改原变量的值

  • 引用类型:传递引用的拷贝

方法中无法更改原变量的引用(指针指向),只可更改引用对象的状态(State)

方法标签(Signature)

  • 方法名称
  • 方法参数

方法返回值类型不是方法标签(不存在同名同参而不同返回值的方法)

对象构造

构造器方法完整定义:

ClassName (ClassPropertiesVariableTable) {
//进行输入参数合法化检查
Property n = Variable;
Statement Block;
}

构造器方法的定义

  • 未定义任何构造器方法 系统会自动产生一个构造器方法,称为无参空默认构造器方法(default constructor) 并将所有实例域初始化为默认值
  • 注意事项
    • 不应在构造器中定义实例域同名变量
    • 在构造器中尽量只调用 final/private 方法(不会(继承后)被子类方法覆盖)
    • this()可调用此类的其他构造方法,this()必须位于构造器方法首行

构造器方法的执行

  • 构造器方法前语句/语句块将先于构造器执行
  • 编译器会在编译时在每个构造器方法内首行自动添加 super();(若父类没有无参构造器方法编译出错)/人工显式调用父类构造器方法,直至实现 Object 类(超类)的构造器方法,再执行构造器方法语句

导入 import

  • 包的导入
import java.包路径.*   //导入指定包的所有类
  • 静态导入
import static java.包路径.类名.*  //导入指令类的所有静态域和静态方法

类路径

package 语句

文档注释

Java 除了可以采用我们常见的注释方式 (///* */ (二型注释不可嵌套)) 之外, Java 语言规范还定义了一种特殊的 Javadoc 注释:

/**
*@author 对类的说明 标明开发该类模块的作者
*@version 对类的说明 标明该类模块的版本
*@see 对类、属性、方法的说明 参考转向,也就是相关主题
*@param 对方法的说明 对方法中某参数的说明
*@return 对方法的说明 对方法返回值的说明
*@exception 对方法的说明 对方法可能抛出的异常进行说明
*@Override 对方法覆盖的说明
*@FunctionalInterface 函数式接口:包含不超过一个abstract方法(可以有其他非abstract方法)
*/

类注释:位于类定义前

/**
*整体性描述
*
* @author 作者
* @version 1.0, 05/22/07
* @since version1.0
*/

方法注释:位于方法定义前

/**
*整体性描述
*
*@param 对方法的说明 对方法中某参数的说明
*@return 对方法的说明 对方法返回值的说明
*@exception/throws 对方法的说明 对方法可能抛出的异常进行说明
*/

域注释:位于实例域定义前

/**
* 备注信息
*/

通用注释

可在文档中看到引用(文本、类/方法/变量、超链接)

  • @see/@link package.class#feature label
  • @see/@link <a href = “……”> label </a>
  • @see/@link “text”

区别: link 注释可在任意位置,see 注释需在类/方法/变量定义前

包注释

新建 package-info.java 源文件:

package 包路径
/**
* 包注释
*/

类设计技巧

数据私有化

保持封装性

数据初始化

不依赖实例域默认值,且应进行数据合法化检查

实例域封装化

过多相关的基本类型实例域可封装成一个轻型类

构造器多样化

最低标准为显式无参构造器+一个带参数(包括合法化检查)构造器

职责明晰化

一个类的方法应与类本身紧密相关,且不过少也不过多

继承

父类与子类(superclass and subclass)

属性的继承

  • 可继承:公有域
  • 不可继承:私有域、静态域、实例域初始化块
  • 若要访问(修改)父类私有域,必须使用调用公有的 super.get()方法得到父类私有域
  • 初始化父类私有域:super(ParamList); 调用父类构造方法进行初始化

方法的继承

  • 可继承:公有方法
  • 不可继承:私有方法、静态方法、构造器方法

方法的覆盖

标签相同(不可降低父类方法可见性)

方法的重载

标签不同,属于新加方法

super 关键字

不是隐式参数,是提示编译器执行的特殊关键字

父类与子类的转换(Is-A 关系)

Subclass must be superclass,superclass may not be subclass.

  • 可将子类引用赋值给父类变量(Upcasting)或替换父类作参数
Person p = new Student();  //p仍是父类变量

注:若父类变量和子类变量引用同一个子类对象实例时,父类某些操作可能引起内存混乱 例如:先调用父类构造器方法构造子类,再调用子类扩展方法访问子类扩展私有域(根本未分配内存空间)

  • 不可将父类引用赋值给子类变量
Student s = new Person();  //ERROR:e.g. s.getStuID();

Object 类

Equals Method

  • 子类中覆盖(@override)父类 equals 方法:super.equals(superClassName other);
  • 显式参数名:Object otherObject
  • if (this == otherObject) return true;
  • if (otherObject == null) return false;
  • if (getClass != otherObject.getClass()) return false;
  • ClassName other = (ClassName) otherObject;
  • return field == other.field

Hash Code Method

  • String 类 hashCode:ΣStringChar[i]^(n-i-1), (i:0~(n-1))
  • Object 对象 hashCode:内部 ID(存储地址)
  • 若重写 equals 方法,也应重写 hashCode 方法,使对象实例 hashCode 分布散列化
    • return 各域 hashCode 值加权和:31x+y rule
      • 引用类型、包装类:hashCode()
      • 数组:Arrays.deepHashCode()
    • return Objects.hash(field1,..,fieldN); //自动组合各域 hashCode
    • hash 值:return (key.hashCode() & 0x7fffffff) % M;

To String Method

  • 设计 return getClass().getName() + ”[“ + field + ”]”;
  • Object 类 toString 方法:用于输出 ClassName 和 hashCode
  • 数组直接继承 Object 类 toString 方法,输出数组需调用 Arrays.(deep)toString();
  • 自动调用:+ 字符串连接符、println(obj)

泛型数组列表

ArrayList<ClassName> VariableName = new ArrayList<>();

  • toArray(ArrayName)转化为同类型普通数组存至 ArrayName:可以创建一个 ArrayList,再转化为数组,方便使用[]下标操作
  • 插入、删除操作时间复杂度高(数据元素左/右移)

对象包装器与自动装箱

Void,Boolean,Byte,Character,Short,Integer, Long, Float, Double 类:包装器(Wrapper)类

父类:Number

final 类(强不可变类):无子类,不可改变数

编译器特性

  • 自动装箱(auto-boxing)
Integer I = 10;
myArrayList.add(10);
  • 自动拆箱(auto-unboxing)
int i= I;
  • 自动装箱+拆箱
Integer I = 0;I++;

// 实际译为:
Integer I = Integer.valueOf(10);
myArrayList.add(Integer.valueOf(10));
Int I = I.intValue();

API 说明

可变参数方法

枚举类

定义

扩展

访问控制符

public>protected(包作用域+)>默认(包作用域)>private(类作用域)

最大限度:不同包的非子类(所有类)、同一个包/不同包的子类、同一个包、同一个类

非访问控制符

abstract

abstract 方法

语法形式:abstract + MethodName(ParamList);

abstract 类
  • 定义
    • 若一个类包含 abstract 方法,则必须是 abstract 类
    • 一个 abstract 类可以不包含 abstract 方法
    • 一个 abstract 类可以包含具体数据和具体方法
  • 构造器方法
    • 需要实现构造器方法
    • 构造器方法可以被非 abstract 子类调用
    • 不能使用 new 构造 abstract 类对象实例

final

final 局部变量(方法内的变量)

只读常量,必须进行一次初始化

final 实例域
  • 必须进行一次(类定义/构造器)初始化
  • final 引用类型实例域的引用不可更改,但所引用对象的状态(State)可被更改
final 方法

可继承,不可重写

final 类
  • 不可继承
  • 实例域可以不是 final 实例域,方法自动成为 final 方法

static

static 实例域(类域)
  • 属于类整体,保存在类的内存区域的公共存储单元(不可继承)
  • 可通过类名/对象实例名访问该属性
static 方法
  • 类方法,属于类整体(不可继承)
  • 没有隐式参数(this/super)
  • 只能处理该类中的 static 实例域/调用该类中的 static 方法
  • 既可通过类名调用该方法(推荐),又可通过对象实例名调用 static 方法
  • Tips:工厂模式:利用 static 方法可模拟构造器方法:可自定义构造器名和返回对象类型

static final 实例域

  • 默认初始化(数值型为 0,布尔型为 false,引用型为 null)
  • 常结合 public 将变量设置为全局静态常量 e.g. e、PI

反射(Reflection)

反射机制

  • 运行中分析 类的能力
  • 运行中查看对象
  • 实现通用的数组操作代码
  • 利用 Method 对象

Class 类

分析类的能力

分析对象

泛型数组实现

调用任意方法(函数指针)

接口与内部类

接口

基本定义

interface 类型是引用类型

常量 + 方法

 [修饰符(public)]interface 接口名 [extends 父接口名列表(多个接口)] {
//常量声明,可为多个
[public] [static] [final] type constantName= Value;
//方法声明,可为多个
[public] [abstract] returnType methodName( [paramList] );
}

接口方法

自动默认:public abstract 方法(声明时无需关键字)

实现接口

在类中必须实现(override)接口中的所有方法

接口作为方法参数

  • 设计此类方法时:
    • 可调用接口中公有静态常量/公有方法(interfaceVariableName.invokeMethod)
    • 可将接口参数传递给其他接口作参数的方法,调用其他方法
  • 实际调用方法时:将实现了该接口的类作为参数传递给方法,可提高方法的灵活性

例子:Comparable 接口和 sort 静态方法

接口变量

  • 不可创建 interface 实例(即不可用 new 关键字)
  • 可声明一个 interface 变量,并使其引用实现了该接口的对象实例
//TimePrinter:实现了ActionListener接口的类
ActionListener myListener = new TimePrinter();

对象克隆

Cloneable Interface

标签接口(tagging interface)之一:无方法

Object Clone Method

浅拷贝: 无法克隆目标对象实例域中的对象成员

Custom Clone Method

鉴于默认 clone 方法的局限性,需自定义用户需要的 clone 方法

  • 实现接口:implements Cloneable
  • 改变可见性&抛出异常: public <returnType> clone() throws CloneNotSupportedException {};
  • 自定义克隆体:克隆子对象

回调

回调设计模式

某个特定事件发生时采取某个特定动作

Action Listener Interface

内部类

内部类调用格式

  • 声明与构造(实例化)

OuterClass.InnerClass variableName = OuterClass/this.new InnerClass();

  • 定义:应使用 private 关键字

  • 访问实例域/方法

内部类:this.fieldName/methodName 外部类:OuterClass.this.fieldName/methodName

局部内部类

  • 定义在方法中的内部类
  • 修饰符:无/abstract/final
  • 可访问外围类成员/final 局部变量

匿名内部类

在实际构造父类/实现接口时定义在构造器方法中的内部类

  • 外围为父类:内部类需要扩展该父类
new SuperType (construction parameters)
{
inner class methods and data{}; //直接定义实例域和方法,构造器参数传递给父类构造器
}
  • 外围为接口:内部类需要实现该接口
new InterfaceType () //一对括号
{
Inner class methods and data{}; //需实现接口中的所有抽象方法
}
  • 例子:积分、线程、回调函数(HookFunction)、事件处理(ActionListener)

静态内部类

  • 只可访问外围类的静态域/静态方法(可视作不可访问外围类)
  • 实例化:new OuterClass.InnerClass()

代理类

图形程序设计

Swing 组件继承层次

Swing 组件功能层次

JFrame

框架基础

位置和大小

  • 方法概览
//继承于:Component类
//功能:设置JFrame的位置和大小
//坐标:相对于电脑屏幕
setLocation(x, y);
setBounds(x, y, width, height);
setLocationByPlatform(true);
  • 动态设置
//得到屏幕大小
Dimension screenSize = Toolkit.getDefaultToolKit().getScreenSize();
int screenWidth = screensSize.width;
int screenHeight = screenSize.height;
//根据屏幕大小设置框架大小
setSize(screenWidth / 2, screenHeight / 2);
setLocationByPlatform(true);

Property Getter and Setter

  • 标题
//继承于:Frame类
//功能:标题属性
public String getTitle();
public void setTitle (String title);
  • 定位
//继承于:Window类
//功能:定位属性
public boolean isLocationByPlatform();
public void setLocationByPlatform (boolean b);
  • 标题图标
Image img = new ImageIcon(“icon.gif”).getImage();
setIconImage(img);
  • 其他属性

自定义绘制组件

所有绘制都使用 Graphics 类作参数(包含绘制图案、图像、文本等的方法)

JComponent Extends

class MyComponent extends JComponent
{ //@override
public void paintComponent (Graphics g)
{
g.drawString(text, x, y);
}
//@override
public Dimension getPreferredSize()
{
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT)
}
}

JPanel Extends

class MyJPanel extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
code for drawing;
}
}

Shape Interface

图形类继承关系图

图形颜色

  • Color 类预定义颜色(Color.XX)
  • SystemColor 类预定义颜色(SystemColor.XX)

事件处理

定义与基础

事件源与事件监听器

实现 Action Listener 接口的事件监听器

适用情况
  • 按钮点击事件(click button)
  • 鼠标双击选择列表框某一选项
  • 选择某一菜单项
  • 文本域键入回车键
  • 组件达到指定时间间隔
事件监听器对象执行其他对象事件源产生事件影响

此时,可使用匿名内部类或 Lambda 表达式简化代码

.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
//code for procedure
}
});

.addActionListener( (e) -> {
//code for procedure
});

Event Handler Class

Adapter Class

此类实现相应接口所有方法,但每个方法方法体皆空;简化 Listener 实现,只需重写所需方法

.addWindowLister(new WindowAdapter()
{
//重写所需方法
});

动作

Action and Abstract Action

Action 接口可连接多个事件源,AbstractAction 类是实现该接口的类(可继承此类编写动作)

基本方法

  • actionPerformed:继承于 ActionListener 接口
  • enabled:启用/禁用动作
  • value:动作对象中的任意名/值 e.g.Action.NAME,“按键名称”
  • key 为动作属性的名称,value 为对应具体属性(如 String、ImageIcon)
  • propertyChangeListener:将动作对象属性变化传给监听器,再传给其他组件对象

动作与点击按钮

  • 将自定义动作与按钮关联
  • JButton 构造器:JButton(Action act);

动作与按键映射

  • 每个组件有三个输入映射和一个动作映射
  • 建立输入映射(三种方式得到(次)顶层组件的输入映射)
InputMap imap = panel.getInputMap(JComponent.InputMapFlag);
  • 关联输入映射和动作映射:put 方法含有两个参数
imap.put(  KeyStroke.getKeyStroke(“ctrl Y)  ,  Object actionMapKeyName );
  • 建立动作映射
ActionMap actionMap = panel.getActionMap();
  • 关联动作映射和动作:put 方法含有两个参数
actionMap.put(Object actionMapKeyName  ,  Action act);

注:将 Object 设为 String ”none” 时 表示 空动作(按键无效)

鼠标事件

AWT 事件继承层次

事件类

  • 语义事件类(semantic):

ActionEvent、AdjustmentEvent、ItemEvent

  • 低级事件类(low-level)

FocusEvent、MouseEvent、MouseWheelEvent、KeyEvent、WindowEvent

事件处理 监听器接口

事件处理 适配器类

  • FocusAdapter
  • MouseAdapter
  • MouseMotionAdapter
  • KeyAdapter
  • WindowAdapter

Swing 组件

Awt 和 Swing 设计中的设计模式

Composite Pattern

将对象组合成树形结构以表示”部分-整体“的层次结构,使得用户对单个对象和组合对象的使用具有一致性

容器与组件(具有共同接口) - 容器与组件具有层次结构,用户可对容器与组件实施同样的操作(点击、删除、输入等)

Decorator Pattern

保持接口,增强性能

以对客户透明的方式动态地给一个对象附加上更多的责任(对象前后本体未变化)

  • 抽象组件(Component)角色: 给出一个抽象接口,以规范准备接收附加责任的对象(透明不变性)
  • 具体组件(ConcreteComponent)角色: 定义一个将要接收附加责任的类(透明不变性)
  • 装饰(Decorator)角色:
    • 持有一个组件对象的实例
    • 定义一个与抽象构件组件接口一致的接口
    • 添加额外功能

具体装饰(ConcreteDecorator)角色: 负责给组件对象“贴上”附加的责任

带滚动条的面板 Component:面板,Decorator:滚动条

Strategy Pattern

动态改变行为

定义了不同的算法族,并且之间可以互相替换

  • 环境对象:实现了抽象策略接口或者引用了具体策略类
  • 抽象策略接口/类:接口/抽象类,环境对象中变化部分
  • 具体策略类:实现了抽象策略接口,可有多个不同的具体策略类(动态变化)

设计原则: 把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口

布局管理器 环境对象:面板,抽象策略:抽象布局管理接口,具体策略:具体布局管理类

Model View Controller Pattern

  • 组件三要素:外观、内容(状态)、行为
  • 模型类:存储内容(状态) state getter/setter
  • 视图类:显示内容(状态)对应外观 一个模型可以有多个视图(模型的不同部分/形式)
  • 控制器类:处理用户输入事件(点击鼠标、敲击键盘),改变模型类/视图类状态,调用模型类/视图类中方法

一个模型类可以适用多个组件(如 DefaultButtonModel 是多种 Button 包装器类的模型对象):

几乎所有组件都有一个带后缀 UI 的视图对象;不是所有组件都有一个专门的控制器对象

简单布局管理器

Flow Layout Class

逐行填充组件,可设置对齐方式和组件间距

Border Layout Class

改变面板大小时,只有中央组件大小变化

技巧:可在五个区块内添加子面板

frame.add(panel, BorderLayout.CENTER/NORTH/SOUTH/WEST/EAST)

Grid Layout Class

组件按行列排列,且大小一致(只能逐行逐列添加组件)

复杂布局管理器

Grid Bag Layout Class

没有行列大小和个数限制的网格布局:行列大小可不一致,可合并相邻行/列(合并单元格)

gridBagPanel.add(component, GridBagConstraints);给每一个组件都构造一个 GridBagConstraints 类

基本步骤
  • 画框图
  • 设置 gridXX 四值
  • 设置 fill/anchor 值、
  • 设置增量 weightx/weight
    • 全部 100:行列可随容器大小变化
    • 设置某一行/列所有 weightx/weighty 为 0:此行/列保持默认大小

e. gridBagPanel.add(component, GridBagConstraints);

Group Layout Class

通过(嵌套)组的水平与垂直计算(间距与组件),实现灵活的布局:

  • GroupLayout 类
  • Group 类
  • ParallelGroup 类
  • SequentialGroup 类

Null Layout

Custom Layout

实现 LayoutManager 接口,自定义 setSizes(Container parent)

在 layoutContainer 方法中调用每个组件的 setBounds 方法,摆放组件

文本组件

JTextComponent 抽象类

文本域

  • JTextField 组件

标签

  • JLabel 组件: 标签无法响应用户输入事件,只提供标识功能

密码域

  • JPassWordField 组件

文本区

  • JTextArea 组件

滚动窗格

  • JScrollPane: 将文本区组件/其他组件插入到滚动窗格中, 可实现文本区/其他组件的滚动.

选择组件

复选框

  • JCheckBox 组件, 勾取选项(可自定义选项标签):勾选/不勾选状态
.addActionListener( if ( .isSelected() ) {……});

多个复选框可共用一个监听器,通过 isSelected 方法检测不同复选框的状态

单选按钮

  • ButtonGroup 对象负责调度任务:保证只有一个 JRadioButton 对象被按下
  • JRadioButton 对象:add 至 JPanel 对象,add 至 ButtonGroup 对象,addActionListener 注册监听器

边框

在面板/子面板(TextPanel、ButtonPanel 功能区等) 调用 setBorder 方法填充边框

组合框

JComboBox 组件,泛型类, 下拉选框(N 个选项 Item),.addActionListener(getItemAt(getSelectedIndex()))

滑动条

JSlider 组件, 可连续选择数值:

.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent event)
{
JSlider source = (JSlider) event.getSource();
int Value = source.getValue();
code for operating; //with Value
}
});

菜单组件

创建菜单

JMenuBar –> JMenu -> JMenuItem

利用 Action 创建 MenuItem:(调用 insert 方法)

Action exitAction = new AbstractAction (Exit) //MenuItems text goes here
{
public void actionPerformed (ActionEvent event)
{
code for action;
}
};

图标菜单项

  • JMenuItem 类扩展 AbstractButton 类
  • 同样地,JMenuItem 类构造器/Action.putValue(Action.SMALL_ICON,……);

单选按钮/复选框菜单项

将 MenuBar 视作 JPanel 即可

弹出菜单

JPopupMenu 组件, 不依附于 MenuBar 的浮动菜单(Window 系统下右键弹出菜单)

快捷键

  • 同样地,两个方式:MenuItem 类构造器/Action.putValue(Action.MNEMONIC_KEY,……);
  • 加速器:不打开菜单项即可起作用的快捷键(如 Ctrl+……),关联 JMenuItem

启用/禁用菜单项

工具栏

  • 同样地,JToolBar 构造器/Action.putValue(Action.SHORT_DESCRIPTION);

对话框(顶级框架)

  • 模式对话框:弹出时不允许用户作其他交互
  • 无模式对话框:弹出时允许用户作其他交互(如工具栏)

选项对话框

  • JOptionPane 组件

自定义对话框

  • 在构造器中调用超类 JDialog 构造器方法
  • 添加对话框的用户界面组件
  • 添加事件处理器
  • 设置对话框大小

文件对话框

  • JFileChooser 组件插入对话框
  • 文件选择器
  • 文件过滤器:可添加文件视图类

颜色对话框

  • JColorChooser 组件插入对话框

异常、断言、日志、调试

处理错误

异常分类

  • 已检查异常:需要抛出声明(非 RuntimeException)
  • 未检查异常:不可控(Error)/可避免(RuntimeException:下标越界等)
  • 子类覆盖父类方法(该方法)抛出必检异常数必须少于父类方法

捕获异常

原则:捕获知道如何处理的异常,传递不知如何处理的异常

捕获多个异常

  • 普通形式
try
{
语句组(可能抛出异常的语句:抛出异常后,try语句块直接终止)
}
catch (匹配Exception ex)
{
子子异常类名 异常处理语句组;
}
catch (匹配Exception ex)
{
子异常类名 异常处理语句组;
}
catch (匹配Exception ex)
{
父异常类名 异常处理语句组;
}
[ finally
{
必定(即使try return)会被执行异常处理语句组:用于释放资源,不能捕获异常
}]

catch:0~n, finally:可选项(无论是否有 break/return,都会被执行多遍)

  • 更好的形式
try
{
try
{
code that might throw exceptions{};
}
finally
{
in.close();
}
}
catch (IOException e)
{
show error message{};
throw exception{};
throw new exception{};
}
  • 常用 catch 处理语句
System.out.println(Error+ e);
System.out,println(Cause+ e.getCause());
throw e;
throw new Exception(String)/(String, e);

重抛异常

  • 将当前捕获的异常再次抛出:throw e;
  • 重新生成并抛出一个新异常(沿调用堆栈传递)
    • throw new Exception("some message");
    • throw new Exception("some message",e);
    • 将原始异常作为新异常的 initCause
catch (SQLException e)
{
Throwable se = new ServletException(“database error”);
se.initCause(e);
throw se;
}

上级便可通过 se.getCause()方法得到原始异常

关闭异常:关闭频率低/不可能发生的异常

catch 语句体为空,便可关闭捕获的异常

记录日志

调试技巧

使用断言

assert 表达式:字符串信息

JUnit 框架单元测试

import static org.JUnit.Assert.*

为每个类构置一个 main 方法进行单元测试

日志代理

Logger.getGlobal().info(" ……" + targetVariableName);

Stack Trace

  • Throwable.PintStackTrace

GUI 调试

泛型

泛型类

自定义类型 Class Person<T> {}

泛型方法

自定义方法 [修饰符] <T> T PeronMethod(Param) {}

泛型变量 T

<T extends SuperClass & Interface>

类型变量用“,”分隔,限定类型用“&”分隔(一个父类+多个接口)

<T extends Comparable & Serializable>

泛型代码

翻译关键:擦除类型参数,用 Object/限定类型代换

  • 虚拟机中没有泛型
  • 多态性:合成桥方法
  • 类型安全性:必要时插入强制类型转换

使用限制

  • T 类型变量:不可为基本类型,必须为引用类型
  • 类型查询(getClass()/instanceof):返回原始类型(如 Person),不返回 T 类型
  • 不可创建参数化类型的数组(如 Person<T>[])
  • 不可实例化类型变量(如 new T()、new T[])
  • 不可在静态域/方法中引用类型变量(如 private static T variableName)
  • 泛型类不可扩展 Throwable 及其子类(因此泛型类不可被抛出/捕获)

通配符类型

<? extends SuperClass>
<? super SubClass>

反射与泛型

集合

集合接口

Collection Interface

Abstract Collection

将 size 和 iterator 抽象化,将 contains、toString 具体化

迭代器
  • 工作位置: 迭代器位于两元素间
  • 工作机制
    • previous 方法:迭代器越过前一元素,并将该元素的引用作为返回值
    • next 方法:迭代器越过下一元素,并将该元素的引用作为返回值
  • 工作方法
    • add 方法:将新元素的引用插入至迭代器当前位置
    • remove 方法:与 previous/next 相互依赖,删除前一次越过元素(不可连续调用 remove 方法)
    • next->( remove )->next->remove
  • 使用原则
    • 给容器附加多个只读迭代器,单独附加唯一一个读写迭代器
    • 并发修改检测: 只检测结构性改变(改变长度),不检测数值性改变(如 set 方法)
Iterable Interface

任何实现了 Iterable 接口及其子接口(如 Collection 接口)的对象都可使用 for each 循环

public interface Iterable<E>
{
Iterator<E> iterator();
}

Queue Interface and Deque Interface

Deque extends Queue extends Collection)

具体集合

数组列表

ArrayList implements List:

  • 随机访问:利用索引值访问元素
  • get/set(int Index)方法:效率高

链表

LinkedList implements List,Deque:

  • 非随机存取:必须从头/尾开始遍历链表访问元素
  • E get(int Index)方法:效率极低

ListIterator:

  • add 方法:依赖于迭代器位置
  • remove 方法:依赖于迭代器状态
  • previousIndex 方法:返回迭代器前一元素的整数索引
  • nextIndex 方法:返回迭代器后一元素的整数索引

散列集

HashSet implements Set:无序无重复元素集,基于 HashTable

  • 散列表:列表/链表数组(多个列表/链表),每个列表/链表成为桶(bucket)
    • 元素的桶的整数索引:元素散列码 mod 桶的总数(余数)
    • 桶数:预计元素个数的 75%~150% e.g 标准类库桶数为 2 的 n 次方,默认值 16
    • 散列冲突(hash collision):目标桶已满
    • 再散列(rehashed):创建大通数(如双倍桶数)的新散列表,丢弃原散列表
    • 装填因子(load factor):再散列时机决定因素,一般为 0.75(75%桶中含有至少一个元素)
    • hash 值:return (key.hashCode() & 0x7fffffff) % M;
  • 方法
    • add:先查找对象存在性,不存在则添加元素
    • contains:重写方法
  • 散列集迭代器:依次访问所有桶

树集

TreeSet implements SortedSet,NavigableSet:有序集

比较接口

Comparable Interface
// A<B负值,A==B零,A>B正值(B代表other)
public interface Comparable<T>
{
int compareTo(T other);
}
Comparator Interface
// A<B负值,A==B零,A>B正值
public interface Comparator<T>
{
int compare(T a, T b);
}

SortedSet<Item> setSortedByName = new TreeSet<>(Comparator comp)//实现比较器的类

队列

  • 双端队列: ArrayDeque 类与 LinkedList 类
  • 优先级队列: PriorityQueue 类, 未对所有元素进行排序
    • add 和 remove 方法: 引用最小元素

映射表

实现 Map 接口,未实现 Collection 接口

  • 散列/比较函数只作用于键 key
  • 添加/删除/检索对象时,必须提供键 key
  • 键 key 具有唯一性

集合框架

RandomAccess 接口:标记接口,无任何方法,标记一个集合是否支持高效的随机访问

集合算法

早期集合

线程

线程基础

线程:分享 CPU、共享内存(多个线程访问同一数据/对象)

线程一般用于需长时间执行的任务:循环、下载、浏览图片

线程状态

Create Thread

创建线程的方法:

  • 父类:继承 Thread 类,重写 run 方法
  • 接口:new Thread(Runnable Task)实现 Runnable 接口的类:实名类/匿名类/Lambda 表达式

Runnable Thread

thread.start() 线程处于可运行状态:可能在运行,可能不在运行,不必始终保持运行

Block Thread

  • blocked
  • waiting
  • timed waiting
blocked

获取锁不得时,进入阻塞状态

waiting

等待调度器时,进入等待状态

timed waiting

调用含超时参数的方法时,进入计时等待状态保持到超时或通知

Object.wait、Thread.sleep、Thread.join、Lock.tryLock、Condition.await

terminated

run 方法正常退出或抛出未捕获异常时,进入(自然/意外)死亡状态

线程属性

优先级

  • 默认情况下继承父线程的优先级
  • 需防止低优先级线程被饿死(因此不要依赖优先级进行编程)
  • MIN_PRIORITY(1)~NORM_PRIORITY(5)~MAX_PRIORITY(10)
  • 每当线程调度器选择新线程时,首选具有较高优先级的线程

Daemon Thread

  • Thread.setDaemon(true)
  • 设置为后台线程:随时可能中断
  • 虚拟机会在只有后台线程时退出,后台线程不可访问固有资源(文件、数据库等)

未捕获异常的处理器

实现 Thread.UncaughtExceptionHandler 接口

不安装默认处理器时,默认处理器为空

中断线程

Interrupt Method

对一个线程调用此方法时,线程将进入中断状态

Interrupted Exception

对一个阻塞线程(调用 sleep/wait 方法等)调用 interrupt 方法时,抛出此异常

线程同步

两个线程都有多个语句,无法保证一个线程所有语句全部执行完再调用另一个线程,必然会出现交错调用不同线程中的语句现象,导致调用混乱现象

锁对象 (实例域)

可重复(持有计数),可共用(共用锁对象的方法可互相调用)

条件对象 (实例域)

管理有锁却不能正常工作的线程

一个锁对象可以有多个相关的条件对象

内部锁

  • synchronized 关键字
  • 每个对象都有一个内部锁,可将静态方法声明为 synchronized
  • 等价于 wait/notifyAll
  • 等价于 await/signalAll

截获内部锁

读写锁

监视器

volatile 关键字:修饰实例域

声明一个域可并发更新,通知编译器和虚拟器注意此特性

死锁

所有线程处于等待或阻塞状态

e.g. 两个线程互相等待状态

Thread Local Helper

线程安全

java.util.concurrent 并发 API:线程安全(同时只有一个线程调用某对象)

原子整数

AtomicInteger.getAndIncrement();     //cnt++;
AtomicInteger.getAndDecrement(); //cnt—
AtomicBooleanAtomicLongAtomicReference

线程安全集合

  • 阻塞队列
  • 高效映射表、队列
  • 写数组列表和写数组集的拷贝 - CopyOnWriteArrayList 类、CopyOnWriteArraySet 类
  • 同步包装器(synchronization wrapper) - 任何集合类通过同步包装器变成线程安全集合类

异步计算

执行器

线程池:创建大量生命周期短的线程

  • CachedThreadPool:提交任务多,创建新线程
  • FixedThreadPool:提交任务多,等待当前任务完成再运行其他任务
  • SingleThreadExecutor:逐一执行提交任务
  • ScheduledExecutorService 接口:预定执行/重复执行任务

以上工厂方法返回:实现 ExecutorService 接口的 ThreadPoolExecutor 对象

  • 创建
ExecutorService pool = Executors.newCachedThreadPool();
  • 方法
pool.execute(myTask);
pool.shutdown();
  • Future 对象用于查询任务完成情况

同步器

线程与 Swing:事件分配线程

事件分配线程不应进行 input/output/sleep 调用(可能使线程阻塞)

  • Timer 类(亦是线程):每隔一段时间重复执行 MyTask
  • 更新图形化界面:SwingUtilities.invokeLater(Runnable MyTask);
EventQueue.invokeLater(new Runnable()
{
public void run()
{
Statements;
}
});
  • 指定布局(Layout)

以下可合成一个方法:

  • 创建组件(Component)
  • 添加组件(getContentPane.add(Component) //得到 Container 类)
  • 响应事件(Event)
  • 设置属性(size、location、bounds、locationByPlatform、title、iconImage、visible、resizable、undecorated、extendedState)
// 取得点击按钮的名字
String itemName = ((JRadioButton) e.getSource()).getText();
//Source:事件源(点击按钮事件)

Self-Defined Class

@override:

  • equals
  • hashCode
  • toString
  • Comparable(compareTo)
  • Cloneable(clone)

常用工具类

  • java.lang Java 语言的核心类库
  • java.util 实用工具
  • java.io 标准输入/输出类库
  • java.awt/javax.swing 图形用户界面(GUI)的类库
  • java.net 网络功能的类库
  • java.sql 数据库访问的类库
  • java.io 输入输出流

输入与输出

输入

  • InputStream 类:read(字节)
  • Reader 类:read(char)

输出

  • OutputStream 类:write、flush、close
  • Writer 类:write(char,String)、flush、close

正则表达式

基本写法

([字符]){数量}\位置.

Group RegExp

  • matcher.group(int)
  • 0 表示整个正则表达式,i 表示第 i 个圆括号

Garbage Collection

Garbage Collection Optimization

GC 优化的核心思路: 尽可能让对象在新生代中分配和回收, 尽量避免过多对象进入老年代, 导致对老年代频繁进行垃圾回收, 同时给系统足够的内存减少新生代垃圾回收次数.

分析系统的运行状况:

  • 系统每秒请求数, 每个请求创建多少对象, 占用多少内存
  • Young GC 触发频率, 对象进入老年代的速率
  • 老年代占用内存, Full GC 触发频率, Full GC 触发的原因, 长时间 Full GC 的原因

GC Tools

  • 监控告警系统:Zabbix、Prometheus、Open-Falcon
  • jdk 自动实时内存监控工具:VisualVM
  • 堆外内存监控: Java VisualVM 安装 Buffer Pools 插件, google perf 工具, Java NMT (Native Memory Tracking) 工具
  • GC 日志分析:GCViewer、gceasy
# jstat:JVM 自带命令行工具, 可用于统计内存分配速率、GC 次数,GC 耗时
jstat -gc <pid> <统计间隔时间> <统计次数>

# jmap:JVM 自带命令行工具, 可用于了解系统运行时的对象分布
jmap -histo <pid>
jmap -dump:live,format=b,file=dump.prof <pid>

# 用来查看正在运行的 Java 应用程序的扩展参数
# 包括 Java System 属性和 JVM 命令行参数
jinfo <pid>

Java Naming Conventions

使用前注意事项

  • 由于 Java 面向对象编程的特性, 在命名时应尽量选择名词
  • 驼峰命名法(Camel-Case)
    • 当变量名或函式名是由一个或多个单字连结在一起,而构成的唯一识别字时,首字母以小写开头,每个单词首字母大写(第一个单词除外)。

包名的书写规范 (Package)

推荐使用公司或机构的顶级域名为包名的前缀,目的是保证各公司/机构内所使用的包名的唯一性。包名全部为小写字母,且具有实际的区分意义。

Package 一般要求

  • 选择有意义的名字,能快速地传达该类的用途。
  • 所有包的命名必须采用小写英文字母。

Package 实际应用

应用系统中经常应用分层,Dao 层(数据库访问)、Service 层(业务处理)、Web 层(页面控制 action 类)

  • 包名的前几个为固定名称, 如果是网站的话,采用网站的域名的反写,如果域名还没有确定的话,采用公司固定的几个名称。如:net.vschool
  • 在包名的接下来一个单词为模块的名称。如:用户模块,包名为 net.vschool.user
  • 关于模块的访问操作,采用分层形式,一般分为:

Dao 层操作:一般定义在 net.vschool.xxx.dao 中,其中 xxx 为模块名称。 Service 层操作:一般定义在 net.vschool.xxx.service 中。 web 层操作:一般定义在 net.vschool.xxx.action 中。

net.vschool.user net.vschool.user.dao net.vschool.user.action net.vschool.user.service

类名的书写规范 (Class)

类名必须使用名词,如果一个类名内含多个单词,那么各个单词第一个字母大写,后续字母小写,起伏呈驼峰状,人称驼峰式命名。给类名命名时,必须保证准确、简洁且容易理解。尽量使用完整单词,避免使用缩写词(除了大家公认的) 类

Class 一般要求

  • 选择有意义的名字,能快速地传达该类的用途。
  • 参照 java 驼峰命名法,类名的首字母必须采用大写的形式,如果类名为多词组合而成的话,那么每个词的首字母必须采用大写。如:StudentAnswer.java
  • 当要区别接口类和实现类的时候,可以在类的后面加上“Impl”。
  • 推荐实体类没有后缀名。
  • public class 应与.java 文件同名

Class 实际应用

应用系统中经常应用分层,Dao 层(数据库访问)、Service 层(业务处理)、Web 层(页面控制 action 类),每一层的类的名称尽量带上该层后缀。

  • Dao 层

    • 接口类:采用 JavaBean+Interface+Dao 的形式来定义,即,实体对象+Interface+Dao
    • 实现类:采用 JavaBean+Interface+Impl+Dao 的形式来定义,即,实体对象+Interface+Impl+Dao
  • Service 层

    • 接口类:采用 Xxx+Interface+Service 的形式来定义,即,模块+Interface+Service
    • 实现类:采用 Xxx+Interface+Impl+Service 的形式来定义,即,模块+Interface+Impl+Service
  • Web 层(action 类)

    • 实现类:采用县 Xxx+Operator+Action 的形式来定义,即,模块+操作+Action

变量的命名

普通变量

Var 一般要求
  • 选择有意义的名字,能快速地传达该变量的用途。
  • 参照 java 驼峰命名法,首字母以小写开头,每个单词首字母大写(第一个单词除外)。
Var 实际应用
  • 变量命名采用基本结构为 typeVariableName,使用 3 字符前缀来表示数据类型。
    • 做数组用时,再加前缀-a,如字符串数组:astr,
    • 自定义类型的变量可以采用本身的名称,把首字母改为小写。
    • 采用名称要能代表在方法中的意义。如果员工列表:employeeList
原词缩写
bytebyt
charchr
floatflt
booleanbln
Integer/intint
shortsht
Long/longlng
Double/doubledbl
stringstr
变量使用技巧
  • 在一段函数中不使用同一个变量表示前后意义不同的两个数值。
  • 除非是在循环中,否则一般不推荐使用单个字母作为变量名,i、j、k 等只作为小型循环的循环索引变量。
  • 避免用 Flag 来命名状态变量。
  • 用 Is 来命名逻辑变量,如:blnFileIsFound。通过这种给布尔变量肯定形式的命名方式,使得其它开发人员能够更为清楚的理解布尔变量所代表的意义。
  • 如果需要对变量名进行缩写时,一定要注意整个代码中缩写规则的一致性。 例如,如果在代码的某些区域中使用 intCnt,而在另一些区域中又使用 intCount,就会给代码增加不必要的复杂性. 建议变量名中尽量不要出现缩写.

静态变量

  • 选择有意义的名字,能快速地传达该变量的用途。
  • 参照 java 驼峰命名法,采用全部大写的形式来书写,对于采用多词合成的变量采用-来连接各单词。如:USER_LIST

方法的命名

Method 一般要求

  • 选择有意义的名字,能快速地传达该方法的用途。
  • 参照 java 驼峰命名法,首字母以小写开头,每个单词首字母大写(第一个单词除外)。

Method 实际应用

  • 方法表示一种行为,它代表一种动作,最好是一个动词或者动词词组或者第一个单词为一个动词。
  • 属性方法:以 get/set 开头,其后跟字段名称,字段名称首字母大写。如:getUserName()
  • 数据层方法:只能以 insert(插入),delete(删除),update(更新),select(查找),count(统计)开头 他层方法避免以这个 5 个单词开头,以免造成误解。
  • 服务层方法,根据方法的行为命名,只描述方法的意义,而不采用方法的目的命名. 比如系统的添加新用户,用户可以前台注册,也可以管理员后台添加,方法会被重用,所以最好不要用使用 register,采用 add 会更好写. 避免使用与 web 层相关的方法.
  • Web 层方法最好是贴近 web 的语言,如 register,login,logout 等方法。