论文部分内容阅读
摘 要:Java语言通过构造器完成数据初始化,在继承过程中子类可以调用父类的构造器。Static关键字可以定义静态属性、静态方法和静态代码块,也可以实现数据初始化,但与构造器有所不同。通过对构造器和Static关键字使用方法的研究,分析单态模式实现的过程。
关键词:构造器;静态;单态模式
中图分类号:TP312.1
Java语言属于完全面向对象的编程语言,代码设计的核心是类的设计。类的设计具有封装的特性,在类中封装了属性的描述和方法的描述,在实例化对象过程中如果采用“对象名.属性名”的方式进行显示初始化赋值显然不符合面向对象编程语言封装的特性,并且当类中属性过多、实例多个对象时,赋值代码会批量增多,书写显的十分臃肿。为了解决这个问题,Java语言提供了构造器技术和静态代码块技术实现属性数据的隐式初始化功能,符合面向对象编程语言封装的特性。
1 构造器
构造器与普通方法不同,普通方法在使用时需要使用“对象名.方法名”进行显示调用,而构造器在对象实例化时能够被Java虚拟机自动调用执行,因此在构造器中对属性成员进行赋值就可以实现隐式自动初始化的功能。在定义上为了区别于普通方法,Java规定构造器的名字必须与类的名字一致,没有返回值,但也不能写void,这样的特殊书写格式能够被Java虚拟机识别[1]。
在类的设计过程中如果没有定义构造器,默认类中包含一个空的构造器,但设计者自定义构造器之后,默认的空构造器就不存了,如果使用者仍然使用空构造器实例化对象,编译系统就会报错,提示空构造器未定义。为了避免这种错误,在类的设计时必须手动编写一个空构造器。当需要设计多个构造器时,可以应用Java重载技术,保证各个构造器中参数的个数或类型不同,在实例化对象时,系统会按照参数的个数和类型进行匹配,找到相应的构造器执行。在构造器中形参命名习惯上与属性命名相同,为了区分属性与形参,可以使用this关键字,属性名前加上“this.”同形参区别开来。此外,在构造器中还可以调用构造器,在同一类中构造器调用构造器采用“this(参数列表)”的格式书写,并且语句必须位于构造器中第一行,否则编译系统会报错,提示“Constructor call must be the first statement in a constructor”。在继承过程中,子类能继承父类的公有属性和公有方法,但不能继承父类的构造器,可以使用super关键字使用“super(参数列表)”的格式调用父类构造器。对于父类构造器调用的语句也必须位于构造器中的第一行。在设计父类时,最好编写一个空构造器,因为子类在继承父类过程中,子类的各个构造器在不指定调用父类指定构造器时,编译系统默认在子类的各个构造器首行调用父类空构造器,如果在父类中未找到空构造器,编译系统会报错,提示“Implicit super constructor FatherClassName() is undefined. Must explicitly invoke another constructor”。如果在子类的构造器中指定调用父类构造器,默认的父类空构造器就不在调用。
2 Static关键字
Java中属性和方法通常是在实例化对象后通过“对象名.属性名”和“对象名.方法名”进行引用,但对于公共的属性和方法,可以通过Static关键字设置成静态成员。对于静态成员的引用除了用对象名引用方法外,还可以通过“类名.属性名”和“类名.方法名”进行引用,由于不用实例化就可直接引用,因此静态属性和静态方法又叫做类的属性和类的方法。
静态属性与非静态属性不同,除了可以被类直接引用特性外,在数据存储上也有区别。对于非静态属性在实例化对象后,在堆内存空间中开辟空间进行数据存储,每实例化一个对象,就分配一份存储空间,而静态属性在堆内存空间中只开辟一次,即数据初始化只有一回,所有实例化的对象共享静态属性数据。
静态方法由于属于类的方法,能够被类直接引用,因此静态方法中只能引用静态属性和其它静态方法,而不能引用非静态属性和非静态方法,因为直接使用类时,还没有实例化对象,非静态属性和非静态方法还没有分配空间进行数据初始化,所以无法引用。而非静态的方法中可以引用非静态的成员,也可以引用静态的成员,因为静态的成员在非静态方法之前初始化。对于main方法,格式为“public static void main(String[]args)”属于静态方法,因此包含main方法的类可以被Java虚拟机直接运行就是这个原理[2]。
静态代码块的格式为“static{代码块;}”,可以对静态属性进行数据初始化。但它与构造器进行数据初始化不同,构造器是调用一次,数据就初始化一次,而静态代码块只初始化一次,并且在构造器进行数据初始化之前完成。对于对象生成计数器类的设计可以定义一个静态整型属性用于计数,可以应用静态代码块进行数据初始化为零,定义构造器中对计数器进行自加操作。
此外还可以用static定义静态内部类,对于静态内部类只能访问外部类的静态属性和静态方法。对于JDK5以上的版本还可以使用静态导入技术,这样一来对于某一个类的所有静态方法直接使用即可,简化了代码的书写。
3 单态模式
单态模式就是在面向对象编程语言中保证一个类只能产生一个实例,在数据库连接、论坛帖子计数器中经常用到,单态模式的使用节省了内存,限制了实例化的个数,便于垃圾回收,在Java中应用构造器和static静态技术的组合就可以实现单态模式。要控制实例化个数,只产生一个实例,就只能在类的内部限制,因为在类的外部无法控制实例化的个数,这个技术通过private关键字对构造器私有化实现,因为私有的成员只能在类的内部使用,在其它类中将无法实例化私有构造器的类。对于不经过实例化就能用的成员只能是静态成员,因此可以通过静态属性和静态方法的使用在类中产生一个实例,实现单态模式[3]。Java对于单态模式的程序设计按照产生实例化对象的阶段不同,可以分为两种情况,一种是使用前产生,另一种是使用时产生。对于使用前产生在定义私有静态属性时就进行实例化赋值,通过公有的静态方法返回实例对象,部分代码如下:
publicclass Singleton {
privatestatic Singleton instance=new Singleton();
private Singleton(){
}
publicstatic Singleton getInstance(){
returninstance;
}
}
另一种使用时实例化的方法是定义私有静态属性时并不实例化赋值,而是在公有的静态方法返回实例对象时对静态属性判断是否为空值,为空值时产生实例化并返回实例化对象。在设计静态方法时要加上synchronized关键字保证线程是同步的,否则会出现多个实例化对象的产生。
4 结束语
Java中构造器技术和static关键字功能充分体现了面向对象语言的特性,全面的对构造器技术和static关键字功能使用的研究,让开发者更充分的理解单态模式的实现的原理,对进一步研究和使用Java技术奠定坚实的基础。
参考文献:
[1]魔乐科技软件实训中心.Java从入门到精通[M].北京:人民邮电出版社,2010.
[2]刘文杰,郑玉,刘志昊.Java 7实用教程[M].北京:清华大学出版社,2013.
[3]张孝祥.Java就业培训教程[M].北京:清华大学出版社,2003.
作者简介:魏钢(1978.11-),男,辽宁盘锦人,讲师,硕士,主要从事Java Web开发研究。
作者单位:锦州师范高等专科学校,辽宁锦州 121000
关键词:构造器;静态;单态模式
中图分类号:TP312.1
Java语言属于完全面向对象的编程语言,代码设计的核心是类的设计。类的设计具有封装的特性,在类中封装了属性的描述和方法的描述,在实例化对象过程中如果采用“对象名.属性名”的方式进行显示初始化赋值显然不符合面向对象编程语言封装的特性,并且当类中属性过多、实例多个对象时,赋值代码会批量增多,书写显的十分臃肿。为了解决这个问题,Java语言提供了构造器技术和静态代码块技术实现属性数据的隐式初始化功能,符合面向对象编程语言封装的特性。
1 构造器
构造器与普通方法不同,普通方法在使用时需要使用“对象名.方法名”进行显示调用,而构造器在对象实例化时能够被Java虚拟机自动调用执行,因此在构造器中对属性成员进行赋值就可以实现隐式自动初始化的功能。在定义上为了区别于普通方法,Java规定构造器的名字必须与类的名字一致,没有返回值,但也不能写void,这样的特殊书写格式能够被Java虚拟机识别[1]。
在类的设计过程中如果没有定义构造器,默认类中包含一个空的构造器,但设计者自定义构造器之后,默认的空构造器就不存了,如果使用者仍然使用空构造器实例化对象,编译系统就会报错,提示空构造器未定义。为了避免这种错误,在类的设计时必须手动编写一个空构造器。当需要设计多个构造器时,可以应用Java重载技术,保证各个构造器中参数的个数或类型不同,在实例化对象时,系统会按照参数的个数和类型进行匹配,找到相应的构造器执行。在构造器中形参命名习惯上与属性命名相同,为了区分属性与形参,可以使用this关键字,属性名前加上“this.”同形参区别开来。此外,在构造器中还可以调用构造器,在同一类中构造器调用构造器采用“this(参数列表)”的格式书写,并且语句必须位于构造器中第一行,否则编译系统会报错,提示“Constructor call must be the first statement in a constructor”。在继承过程中,子类能继承父类的公有属性和公有方法,但不能继承父类的构造器,可以使用super关键字使用“super(参数列表)”的格式调用父类构造器。对于父类构造器调用的语句也必须位于构造器中的第一行。在设计父类时,最好编写一个空构造器,因为子类在继承父类过程中,子类的各个构造器在不指定调用父类指定构造器时,编译系统默认在子类的各个构造器首行调用父类空构造器,如果在父类中未找到空构造器,编译系统会报错,提示“Implicit super constructor FatherClassName() is undefined. Must explicitly invoke another constructor”。如果在子类的构造器中指定调用父类构造器,默认的父类空构造器就不在调用。
2 Static关键字
Java中属性和方法通常是在实例化对象后通过“对象名.属性名”和“对象名.方法名”进行引用,但对于公共的属性和方法,可以通过Static关键字设置成静态成员。对于静态成员的引用除了用对象名引用方法外,还可以通过“类名.属性名”和“类名.方法名”进行引用,由于不用实例化就可直接引用,因此静态属性和静态方法又叫做类的属性和类的方法。
静态属性与非静态属性不同,除了可以被类直接引用特性外,在数据存储上也有区别。对于非静态属性在实例化对象后,在堆内存空间中开辟空间进行数据存储,每实例化一个对象,就分配一份存储空间,而静态属性在堆内存空间中只开辟一次,即数据初始化只有一回,所有实例化的对象共享静态属性数据。
静态方法由于属于类的方法,能够被类直接引用,因此静态方法中只能引用静态属性和其它静态方法,而不能引用非静态属性和非静态方法,因为直接使用类时,还没有实例化对象,非静态属性和非静态方法还没有分配空间进行数据初始化,所以无法引用。而非静态的方法中可以引用非静态的成员,也可以引用静态的成员,因为静态的成员在非静态方法之前初始化。对于main方法,格式为“public static void main(String[]args)”属于静态方法,因此包含main方法的类可以被Java虚拟机直接运行就是这个原理[2]。
静态代码块的格式为“static{代码块;}”,可以对静态属性进行数据初始化。但它与构造器进行数据初始化不同,构造器是调用一次,数据就初始化一次,而静态代码块只初始化一次,并且在构造器进行数据初始化之前完成。对于对象生成计数器类的设计可以定义一个静态整型属性用于计数,可以应用静态代码块进行数据初始化为零,定义构造器中对计数器进行自加操作。
此外还可以用static定义静态内部类,对于静态内部类只能访问外部类的静态属性和静态方法。对于JDK5以上的版本还可以使用静态导入技术,这样一来对于某一个类的所有静态方法直接使用即可,简化了代码的书写。
3 单态模式
单态模式就是在面向对象编程语言中保证一个类只能产生一个实例,在数据库连接、论坛帖子计数器中经常用到,单态模式的使用节省了内存,限制了实例化的个数,便于垃圾回收,在Java中应用构造器和static静态技术的组合就可以实现单态模式。要控制实例化个数,只产生一个实例,就只能在类的内部限制,因为在类的外部无法控制实例化的个数,这个技术通过private关键字对构造器私有化实现,因为私有的成员只能在类的内部使用,在其它类中将无法实例化私有构造器的类。对于不经过实例化就能用的成员只能是静态成员,因此可以通过静态属性和静态方法的使用在类中产生一个实例,实现单态模式[3]。Java对于单态模式的程序设计按照产生实例化对象的阶段不同,可以分为两种情况,一种是使用前产生,另一种是使用时产生。对于使用前产生在定义私有静态属性时就进行实例化赋值,通过公有的静态方法返回实例对象,部分代码如下:
publicclass Singleton {
privatestatic Singleton instance=new Singleton();
private Singleton(){
}
publicstatic Singleton getInstance(){
returninstance;
}
}
另一种使用时实例化的方法是定义私有静态属性时并不实例化赋值,而是在公有的静态方法返回实例对象时对静态属性判断是否为空值,为空值时产生实例化并返回实例化对象。在设计静态方法时要加上synchronized关键字保证线程是同步的,否则会出现多个实例化对象的产生。
4 结束语
Java中构造器技术和static关键字功能充分体现了面向对象语言的特性,全面的对构造器技术和static关键字功能使用的研究,让开发者更充分的理解单态模式的实现的原理,对进一步研究和使用Java技术奠定坚实的基础。
参考文献:
[1]魔乐科技软件实训中心.Java从入门到精通[M].北京:人民邮电出版社,2010.
[2]刘文杰,郑玉,刘志昊.Java 7实用教程[M].北京:清华大学出版社,2013.
[3]张孝祥.Java就业培训教程[M].北京:清华大学出版社,2003.
作者简介:魏钢(1978.11-),男,辽宁盘锦人,讲师,硕士,主要从事Java Web开发研究。
作者单位:锦州师范高等专科学校,辽宁锦州 121000