第一章 声明与访问控制
1.2 标识符和JavaBeans
1.2.1 合法标识符
由Unicode字符、数字、货币符号、连字符组成。Unicode字符这里可以理解为"可以组成字的符号"。换句话说只要你高兴,用中文命名变量也可以。但是一些特殊的符号是不能用的,比如+-./等.
必须知道的几条规则:
[color=red]不能以数字开头,必须以"字母"、"$"、"_"开头,只可以用字母,货币符号,连字符或者数字[/color]。
[color=red]关键字不能用作标识符,注意1.4新增assert,1.5新增enum。其他不常用的关键字:const,native,strictfp,transient,volatile,instanceof[/color].
大小写敏感
一些非法的标识符:
Java代码
int :b; //:非法
int -d; //-非法
int e#; //#非法
int .f; //.非法
int 7g; //不能以数字开头
1.2.2 Sun的Java编码规范
Sun的一些命名建议:
类和接口。首字母大写,驼峰命名法,名词。
方法。首字母小写,驼峰命名法,动词-名词组合。
变量。首字母小写,驼峰命名法,有意义的短名称。
常量。[color=red]表示为static和final的变量。全部大写,并以下划线做分隔符。例如 MIN_HEIGHT[/color]
1.2.3 JavaBeans标准
JavaBeans由两部分组成:属性(property)和事件监听器(event listener)。
属性就是JavaBean的私有变量,以及访问属性的对应getter,setter方法。
JavaBeans属性命名规则:
必须是public方法
getProperty(),setProperty(String property),[color=red]如果是布尔值,那么就可以用is和get[/color]。
JavaBeans 监听器命名规则:
必须是public方法
[color=red]向事件源注册的监听方法以“add”开头
取消注册的方法以“remove”开头[/color]
要操作的监听器类型必须作为变元传递给方法(addXListener(MyListener m) 错误)
必须以“Listener”结尾
不规范的例子:
Java代码
void setCustomerName(String s) //must be public
public void modifyMyValue(int v) //can't be 'modify'
public void addXListener(MyListener m) //listener type mismatch
1.3 声明类
1.3.2 类声明和修饰符
修饰符分为两类:
访问修饰符:public 默认
非访问修饰符:strictfp final abstract
当类A可以访问类B时,即B对A可见(visibility),这意味着类A可以:
创建类B的一个实例(instance)
扩展(extend)类B,就是继承B
访问(access)类B,就是访问类B的某些变量和方法,当然这取决与他们的访问修饰符
其他(非访问)类修饰符:strictfp final abstract
strictfp 对于考试,我们只要知道它是关键字就可以了。它可以修饰类和方法,但不可用于变量。作用是声明该类或方法在处理浮点数时将遵守IEEE754标准。否则在处理浮点数时可能与平台相关。
final 最终类。该类不能再有子类,即不能被继承。
abstract 抽象类。与final相反,就是让你继承来实现的。[color=red]其永远不能被实例化。[/color]
[color=red]抽象类中的方法一分号结尾,而不是波形括号。
public abstract void goFast();接口也一样,因为接口中所有的方法都是抽象的。[/color]
1.4 声明接口
1.4.1 声明接口
接口就是一份契约(contract),说明它能够做什么。任何实现这个接口的类都必须同意为该接口的所有方法提供实现。
接口方法隐含都是公共的和抽象的,所以不必实际地键入public或abstract修饰符。
接口只能声明常量,不能声明实例变量。
接口方法一定不能是静态的。因为接口方法是abstract的,是必须被实现的。
[color=red]接口可以继承1个或者多个接口,并且只能继承接口,不能继承类。
接口不能implements另一个接口或类。
[/color]
[color=red]合法的非抽象实现类具有如下属性:
1 为接口的所有方法实现具体实现。
2 一定不能为实现的方法声明新的检验异常
3一定不能声明比该接口方法中所声明的异常更宽泛的任何检验异常
4可以在任何接口实现方法实现上声明运行异常
5必须包含与它所实现方法完全相同的方法签名和返回类型(不必声明该接口的异常)。
实现接口的类本身可以是抽象的[/color]
接口类型能够被多态地使用。
1.4.2 声明接口常量
接口中可以定义常量,而且都是public static final的,常量一旦被定义是无法修改或重新赋值的。
1.5 声明类成员
1.5.1 访问修饰符
类成员可以使用全部4种访问修饰符,包括:public protected private 和默认。
子类不可以重写父类的私有方法,看起来是重写,但是只是和私有方法的名字相同,但这种情况不属于override.
[color=red]默认成员只允许同一包之内的访问,子类也不能访问(除非子类也在同一包内),这和保护成员不同。[/color]
对于protected的成员变量,在包外可以通过继承来访问父类的protected成员。但是,在子类中实例化父类,用"."的类引用方式是无法访问的。
[color=red]超类保护成员对继承超类的子类(或该子类的子类)都是可见的(直接访问,不能通过.类引用),但是对和子类在同一个包中的别的类不可见,也就是在该无关类中实例化子类后,也不能访问超类的保护成员,即不可见![/color]
对于局部变量,不可以使用访问修饰符[color=red](private,public等都不可用)。局部变量唯一一个可以使用的修饰符是final。[/color]
4种访问级别的可访问范围:
访问级别访问控制修饰符 同类 同包 同包子类 包外子类 包外
公开 public √ √ √ √ √
受保护 protected √ √ √ 继承可以 -
默认 √ √ √ - -
私有 private √ - - - - -
1.5.2 非访问修饰符
类的成员变量可以使用的非访问修饰符:
final、abstract、static、transient、synchronized、native、strictfp
同步方法:
synchronized方法一次只能被一个线程访问,只能应用于方法(不用于变量和类),可以使用所有的访问控制级别(public,private...)。
本地方法:
native修饰符表明方法是用与平台相关的语言(通常为C)实现的。只能应用于方法(不用于变量和类)。它实质上就是一个本地接口,比如 public native void runFormC();
strictfp方法:
跟修饰类的时候一样,它可以修改类或方法,不能用于变量。
具有可变变元列表的方法(var-arg):
数量可变的变元。要注意:
var-arg必须制定它的变元类型,即它是int?char?还是Object?
一个使用var-arg的方法中有其他参数是合法的。
var-arg必须是方法签名中的最后一个参数,且一个方法中只能有一个var-arg。
合法的var-arg声明:
Java代码
void doStuff(int...x){}
void doStuff(char c,int...is){}
void doStuff(Object...objects){}
1.5.3 构造函数声明
构造函数没有返回类型。
构造函数的名称必须与类名一致。
不能标识为static、final、abstract
Java代码
class Foo2{
//legal constructors
Foo2(){ }
private Foo2(byte b){ }
Foo2(int x){ }
//illegal constructors
void Foo2(){ } //it's a method,not a constructor
Foo2(){ } //not a method or a constructor
Foo2(short s); //looks like an abstract method
static Foo2(float f){ }//can't be static
final Foo2(long x){ }//can't be final
abstract Foo2(char c){ }//can't be abstract
Foo2(int... x,int t){ }//bad var-arg syntax
}
1.5.4 变量声明
两种类型的变量:
基本变量:char,boolean,byte,short,int,long,double,float
引用变量:用于引用(访问)一个对象。
基本变量的范围:
类型 位 字节 最小范围 最大范围
byte 8 1 -2^7 2^7-1
short 16 2 -2^15 2^15-1
int 32 4 -2^31 2^31-1
long 64 8 -2^63 2^63-1
float 32 4 -- --
double 64 8 -- --
[color=red]对考试而言,只需知道前两列[/color]
声明引用变量
Java代码
Object o;
String str;
实例变量
实例变量定义在类中,但位于任何方法之外,并且只有在实例化类时才会被初始化。
实例变量可以使用所有4种访问修饰符。
可以标识为final、transient
不可以标识为abstract、synchronized、strictfp、native
不可以标识为static,否则就是类变量(静态变量)了。
局部(自动/栈/方法)变量
局部变量是在方法内声明的变量,作用域只在方法内部。可以用的修饰符只有final。[color=red]必须在使用前初始化局部变量[/color]
数组声明
Java中,在声明数组中不可指定数组的大小,只有在实例化的时候,JVM才分配空间。
Java代码
int[] key;
int key [];
int key[];
String[][][] str;
String[] str [];
对象数组能够保存通过该数组声明类型IS-A(或者instanceof)测试的任何对象。例如,Horse extends Animal,那么Horse对象就能够放入Animal数组中。
final变量
对于声明为final的基本变量,只是说它们的值不可以修改;而对于引用变量,是指不能修改“引用”了,仍然可以修改该引用的对象的数据。
transient变量
表示为瞬态的,则是在告诉JVM,当试图序列化包含这个变量的对象时应跳过它。不需熟悉。
volatile变量
volatile告诉JVM,访问该变量的线程必须总是使自己对该变量的私有副本与内存中的主副本保持一致。不需熟悉。
静态变量和静态方法
static成员独立于为类而创建的任何实例
修饰符使用表:
修饰符 类 成员方法 构造方法 成员变量 局部变量
abstract(抽象的) √ √ - - -
static(静态的) - √ - √ -
public(公共的) √ √ √ √ -
protected(受保护的) - √ √ √ -
private(私有的) - √ √ √ -
synchronized(同步的) - √ - - -
native(本地的) - √ - - -
transient(暂时的) - - - √ -
volatile(易失的) - - - √ -
final(不可改变的) √ √ - √ √
1.5.5 声明枚举
枚举就是限制一个变量只能具有几个预定义的值中的某个值。
枚举可以被[color=red]声明为独立的类,类成员,但是不能在方法内声明它们[/color]。
声明枚举的方式:
Java代码
enum CoffeeSize {BIG,HUGE,OVERWHELMING}; //在这个枚举声明的后面没有其他声明的情况下,可以加一个分号
枚举类中的构造函数:
Java代码
enum CoffeeSize{
BIG(8),HUGE(10),OVERWHELMING(16);
CoffeeSize(int ounces){
this.ounces = ounces;
}
private int ounces;
public int getOunces(){
return ounces;
}
}
[color=red]可直接将枚举作为一个类成员。[/color]
1.2 标识符和JavaBeans
1.2.1 合法标识符
由Unicode字符、数字、货币符号、连字符组成。Unicode字符这里可以理解为"可以组成字的符号"。换句话说只要你高兴,用中文命名变量也可以。但是一些特殊的符号是不能用的,比如+-./等.
必须知道的几条规则:
[color=red]不能以数字开头,必须以"字母"、"$"、"_"开头,只可以用字母,货币符号,连字符或者数字[/color]。
[color=red]关键字不能用作标识符,注意1.4新增assert,1.5新增enum。其他不常用的关键字:const,native,strictfp,transient,volatile,instanceof[/color].
大小写敏感
一些非法的标识符:
Java代码
int :b; //:非法
int -d; //-非法
int e#; //#非法
int .f; //.非法
int 7g; //不能以数字开头
1.2.2 Sun的Java编码规范
Sun的一些命名建议:
类和接口。首字母大写,驼峰命名法,名词。
方法。首字母小写,驼峰命名法,动词-名词组合。
变量。首字母小写,驼峰命名法,有意义的短名称。
常量。[color=red]表示为static和final的变量。全部大写,并以下划线做分隔符。例如 MIN_HEIGHT[/color]
1.2.3 JavaBeans标准
JavaBeans由两部分组成:属性(property)和事件监听器(event listener)。
属性就是JavaBean的私有变量,以及访问属性的对应getter,setter方法。
JavaBeans属性命名规则:
必须是public方法
getProperty(),setProperty(String property),[color=red]如果是布尔值,那么就可以用is和get[/color]。
JavaBeans 监听器命名规则:
必须是public方法
[color=red]向事件源注册的监听方法以“add”开头
取消注册的方法以“remove”开头[/color]
要操作的监听器类型必须作为变元传递给方法(addXListener(MyListener m) 错误)
必须以“Listener”结尾
不规范的例子:
Java代码
void setCustomerName(String s) //must be public
public void modifyMyValue(int v) //can't be 'modify'
public void addXListener(MyListener m) //listener type mismatch
1.3 声明类
1.3.2 类声明和修饰符
修饰符分为两类:
访问修饰符:public 默认
非访问修饰符:strictfp final abstract
当类A可以访问类B时,即B对A可见(visibility),这意味着类A可以:
创建类B的一个实例(instance)
扩展(extend)类B,就是继承B
访问(access)类B,就是访问类B的某些变量和方法,当然这取决与他们的访问修饰符
其他(非访问)类修饰符:strictfp final abstract
strictfp 对于考试,我们只要知道它是关键字就可以了。它可以修饰类和方法,但不可用于变量。作用是声明该类或方法在处理浮点数时将遵守IEEE754标准。否则在处理浮点数时可能与平台相关。
final 最终类。该类不能再有子类,即不能被继承。
abstract 抽象类。与final相反,就是让你继承来实现的。[color=red]其永远不能被实例化。[/color]
[color=red]抽象类中的方法一分号结尾,而不是波形括号。
public abstract void goFast();接口也一样,因为接口中所有的方法都是抽象的。[/color]
1.4 声明接口
1.4.1 声明接口
接口就是一份契约(contract),说明它能够做什么。任何实现这个接口的类都必须同意为该接口的所有方法提供实现。
接口方法隐含都是公共的和抽象的,所以不必实际地键入public或abstract修饰符。
接口只能声明常量,不能声明实例变量。
接口方法一定不能是静态的。因为接口方法是abstract的,是必须被实现的。
[color=red]接口可以继承1个或者多个接口,并且只能继承接口,不能继承类。
接口不能implements另一个接口或类。
[/color]
[color=red]合法的非抽象实现类具有如下属性:
1 为接口的所有方法实现具体实现。
2 一定不能为实现的方法声明新的检验异常
3一定不能声明比该接口方法中所声明的异常更宽泛的任何检验异常
4可以在任何接口实现方法实现上声明运行异常
5必须包含与它所实现方法完全相同的方法签名和返回类型(不必声明该接口的异常)。
实现接口的类本身可以是抽象的[/color]
接口类型能够被多态地使用。
1.4.2 声明接口常量
接口中可以定义常量,而且都是public static final的,常量一旦被定义是无法修改或重新赋值的。
1.5 声明类成员
1.5.1 访问修饰符
类成员可以使用全部4种访问修饰符,包括:public protected private 和默认。
子类不可以重写父类的私有方法,看起来是重写,但是只是和私有方法的名字相同,但这种情况不属于override.
[color=red]默认成员只允许同一包之内的访问,子类也不能访问(除非子类也在同一包内),这和保护成员不同。[/color]
对于protected的成员变量,在包外可以通过继承来访问父类的protected成员。但是,在子类中实例化父类,用"."的类引用方式是无法访问的。
[color=red]超类保护成员对继承超类的子类(或该子类的子类)都是可见的(直接访问,不能通过.类引用),但是对和子类在同一个包中的别的类不可见,也就是在该无关类中实例化子类后,也不能访问超类的保护成员,即不可见![/color]
对于局部变量,不可以使用访问修饰符[color=red](private,public等都不可用)。局部变量唯一一个可以使用的修饰符是final。[/color]
4种访问级别的可访问范围:
访问级别访问控制修饰符 同类 同包 同包子类 包外子类 包外
公开 public √ √ √ √ √
受保护 protected √ √ √ 继承可以 -
默认 √ √ √ - -
私有 private √ - - - - -
1.5.2 非访问修饰符
类的成员变量可以使用的非访问修饰符:
final、abstract、static、transient、synchronized、native、strictfp
同步方法:
synchronized方法一次只能被一个线程访问,只能应用于方法(不用于变量和类),可以使用所有的访问控制级别(public,private...)。
本地方法:
native修饰符表明方法是用与平台相关的语言(通常为C)实现的。只能应用于方法(不用于变量和类)。它实质上就是一个本地接口,比如 public native void runFormC();
strictfp方法:
跟修饰类的时候一样,它可以修改类或方法,不能用于变量。
具有可变变元列表的方法(var-arg):
数量可变的变元。要注意:
var-arg必须制定它的变元类型,即它是int?char?还是Object?
一个使用var-arg的方法中有其他参数是合法的。
var-arg必须是方法签名中的最后一个参数,且一个方法中只能有一个var-arg。
合法的var-arg声明:
Java代码
void doStuff(int...x){}
void doStuff(char c,int...is){}
void doStuff(Object...objects){}
1.5.3 构造函数声明
构造函数没有返回类型。
构造函数的名称必须与类名一致。
不能标识为static、final、abstract
Java代码
class Foo2{
//legal constructors
Foo2(){ }
private Foo2(byte b){ }
Foo2(int x){ }
//illegal constructors
void Foo2(){ } //it's a method,not a constructor
Foo2(){ } //not a method or a constructor
Foo2(short s); //looks like an abstract method
static Foo2(float f){ }//can't be static
final Foo2(long x){ }//can't be final
abstract Foo2(char c){ }//can't be abstract
Foo2(int... x,int t){ }//bad var-arg syntax
}
1.5.4 变量声明
两种类型的变量:
基本变量:char,boolean,byte,short,int,long,double,float
引用变量:用于引用(访问)一个对象。
基本变量的范围:
类型 位 字节 最小范围 最大范围
byte 8 1 -2^7 2^7-1
short 16 2 -2^15 2^15-1
int 32 4 -2^31 2^31-1
long 64 8 -2^63 2^63-1
float 32 4 -- --
double 64 8 -- --
[color=red]对考试而言,只需知道前两列[/color]
声明引用变量
Java代码
Object o;
String str;
实例变量
实例变量定义在类中,但位于任何方法之外,并且只有在实例化类时才会被初始化。
实例变量可以使用所有4种访问修饰符。
可以标识为final、transient
不可以标识为abstract、synchronized、strictfp、native
不可以标识为static,否则就是类变量(静态变量)了。
局部(自动/栈/方法)变量
局部变量是在方法内声明的变量,作用域只在方法内部。可以用的修饰符只有final。[color=red]必须在使用前初始化局部变量[/color]
数组声明
Java中,在声明数组中不可指定数组的大小,只有在实例化的时候,JVM才分配空间。
Java代码
int[] key;
int key [];
int key[];
String[][][] str;
String[] str [];
对象数组能够保存通过该数组声明类型IS-A(或者instanceof)测试的任何对象。例如,Horse extends Animal,那么Horse对象就能够放入Animal数组中。
final变量
对于声明为final的基本变量,只是说它们的值不可以修改;而对于引用变量,是指不能修改“引用”了,仍然可以修改该引用的对象的数据。
transient变量
表示为瞬态的,则是在告诉JVM,当试图序列化包含这个变量的对象时应跳过它。不需熟悉。
volatile变量
volatile告诉JVM,访问该变量的线程必须总是使自己对该变量的私有副本与内存中的主副本保持一致。不需熟悉。
静态变量和静态方法
static成员独立于为类而创建的任何实例
修饰符使用表:
修饰符 类 成员方法 构造方法 成员变量 局部变量
abstract(抽象的) √ √ - - -
static(静态的) - √ - √ -
public(公共的) √ √ √ √ -
protected(受保护的) - √ √ √ -
private(私有的) - √ √ √ -
synchronized(同步的) - √ - - -
native(本地的) - √ - - -
transient(暂时的) - - - √ -
volatile(易失的) - - - √ -
final(不可改变的) √ √ - √ √
1.5.5 声明枚举
枚举就是限制一个变量只能具有几个预定义的值中的某个值。
枚举可以被[color=red]声明为独立的类,类成员,但是不能在方法内声明它们[/color]。
声明枚举的方式:
Java代码
enum CoffeeSize {BIG,HUGE,OVERWHELMING}; //在这个枚举声明的后面没有其他声明的情况下,可以加一个分号
枚举类中的构造函数:
Java代码
enum CoffeeSize{
BIG(8),HUGE(10),OVERWHELMING(16);
CoffeeSize(int ounces){
this.ounces = ounces;
}
private int ounces;
public int getOunces(){
return ounces;
}
}
[color=red]可直接将枚举作为一个类成员。[/color]