本文主要总结了一些自己不太熟悉的概念。
对象与对象变量
Date birthday = new Date();
对象变量:birthday 对象:右边的部分
一个对象变量并没有实际包含一个对象,仅仅是引用一个对象。
可以显示地将对象变量设置为null
,表明这个对象变量目前没有引用任何对象:
birthday = null;
隐式参数与显式参数
例,methodName()是类class1的方法,
calss class1{
int a;
public void methodName(int b){
this.a = b ;
}
- 显式参数(explicit):括号里面的,例如double pName
- 隐式参数(implicit):出现在方法名前的class1类对象 -- 关键词
this
表示隐式参数。例如this.a
封装
不能编写返回引用可变对象
的访问器方法!例如:
class class1{
private Date a;
public Date get(){
return Date a; //会破坏封装性!
}
}
以上操作破坏了a
的私有性。
改正方法:克隆(clone)
class class1{
private Date a;
public Date get(){
return Date a.clone(); //使用clone()
}
}
final实例域
class class1{
private final String name;
}
final域的特征:
- 构造对象时,必须初始化final
- 后面操作中,不能再改动
- 但并不等于常量!
- 属于对象,并不是类!
static静态
static域
每个类只能有一个static域
同一类的所有对象共享一个static域
即使没有对象,static域也存在。它属于类,不属于任何一个对象
class Employee{ private static int nextId = 1; private int id; }
static常量
如下例,在程序中,可以使用
Math.PI
来获取这个常量。public class Math{ public static final double PI = 3.14; }
static方法
Math.pow(x,a)
- 不使用任何对象;
- 不能操作实例域(即类内的非static方法和变量),因为它不能操作对象;
- 可以访问自身类的static域;
- 对象也可以调用static方法。
在下面两种情况使用静态方法:
- 一个方法不需要访问对象;
- 一个方法只需要访问类的static域。
工厂方法
工厂方法是静态方法的一种常见用途。 例如,NumberFormat
使用工厂方法(而不是构造器)产生不同风格的格式对象。
NumberFormat a = NumberFormat.getSytleA();
NumberFormat b = NumberFormat.getStyleB();
main方法
public class Application{
public static void main(String[] args){
// construct objects here
}
}
- 每一个类可以有一个main方法,用来单元测试;
- 多个类被调用时,只会执行一个main方法;
初始化块
构造对象时,先运行初始化块,才运行构造器主体部分。
class Employee{
private static int nextId;
private int id;
//初始化块
{
id=nextId;
}
}
如果对类的静态域进行初始化的代码比较复杂,就可以使用静态的初始化块:
static{
Random generator = new Random();
nextId = generator.nextId(10000);
}
类(!!!不是对象)第一次加载时,将会进行static域的初始化。
初始化数据域的三种方法
- 在构造器中设置值
- 在声明中赋值
- 在初始化块中赋值
类的初始化顺序
对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。
例如,
public class InitialOrderTest {
// 静态变量
public static String staticField = "静态变量";
// 变量
public String field = "变量";
// 静态初始化块
static {
System.out.println(staticField);
System.out.println("静态初始化块");
}
// 初始化块
{
System.out.println(field);
System.out.println("初始化块");
}
// 构造器
public InitialOrderTest() {
System.out.println("构造器");
}
public static void main(String[] args) {
new InitialOrderTest();
}
}
运行以上代码,我们会得到如下的输出结果:
静态变量
静态初始化块
变量
初始化块
构造器
对于继承的情况:
class Parent {
// 静态变量
public static String p_StaticField = "父类--静态变量";
// 变量
public String p_Field = "父类--变量";
// 静态初始化块
static {
System.out.println(p_StaticField);
System.out.println("父类--静态初始化块");
}
// 初始化块
{
System.out.println(p_Field);
System.out.println("父类--初始化块");
}
// 构造器
public Parent() {
System.out.println("父类--构造器");
}
}
public class SubClass extends Parent {
// 静态变量
public static String s_StaticField = "子类--静态变量";
// 变量
public String s_Field = "子类--变量";
// 静态初始化块
static {
System.out.println(s_StaticField);
System.out.println("子类--静态初始化块");
}
// 初始化块
{
System.out.println(s_Field);
System.out.println("子类--初始化块");
}
// 构造器
public SubClass() {
System.out.println("子类--构造器");
}
// 程序入口
public static void main(String[] args) {
new SubClass();
}
}
运行一下上面的代码,结果马上呈现在我们的眼前:
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
总得来说,是先静态后变量,先父类后子类
其他重点
- 基于类的访问权限:一个方法可以访问所属类的所有私有数据。
- java的值引用(基本数据类型、对象引用)
- 如果类中提供了至少一个有参构造器,而没有无参构造器,则在构造无参对象时会出错。
Java类库中的GregorianCalendar类 (删除本节)
纪元
时间是用距离一个固定时间点的毫秒数表示的,这个点就是纪元(epoch)。
时间与日历
为了将时间与日历分开,标准Java类库分别包含两个类:
- Date类:用来表示时间点的类;
- GregorianCalendar类:用来表示公历法的类;(通过它还有一个扩展类——Calendar类,描述了日历的一般属性)
Date类
用来表示时间的类;
只有少量的方法,例如比较两个时间点before(),after():
doday.before(birthday)
GregorianCalendar类
常见方法:
new GregorianCalendar()
,构造新的对象,用于表示对象构造时的日期和时间;
例如:
GregorianCalendar g1 = new GregorianCalendar();
new GregorianCalendar(1999,11,31)
,提供年月日构造一个表示特定日期午夜的日历对象。(月份从0开始计数,11表示12月)
new GregorianCalendar(1991,Calendar.DECEMBER,31)
,与上等价
new GregorianCalendar(1991,Calendar.DECEMBER,31,23,59,59)
,设置时间