在Java中,构造函数的访问级别通常是public, 它提供了一个构造该类对象的接口。可是你知不知道,把构造函数的级别设为private, 有一些特别用处。
先来看一段代码:
//Shape.java
public class Shape {
private Shape() {
/* set something here */
}
public static Shape makeShape(/* arglist */) {
System.out.println("here is the shape you ordered");
return (new Shape());
}
public static void main(String args[]) {
Shape.makeShape();
}
}
首先从语言角度分析,我们可以知道, 任何类的使用者都无法使用构造函数来生成一个图形, 因为构造函数是私有的,无法被类以外的函数使用。而只能通过调用makeShape来实现。
也许你会问,为什么不直接使用构造函数来生成图形,而需要使用一个看上去多余的makeShape方法呢?
这样做有以下几个好处:
1。你可以返回任何的Shape类型,包括Shape的子类。比如你可以把makeShape写成这样:
public static Shape makeShape(/* arglist */) {
System.out.println("here is the shape you ordered");
if (retangle)
return (new Retangle(/* arglist*/));
if (Circle)
return (new Circle(/* arglist */));
/* you can return as many shapes as you like */
}
这里假设Retangle 和 Circle 都是shape的子类,并且和Shape类在同一个包內,Shape类可以访问子类的构造函数。这样shape就提供了一个图形工厂。 用户通过一个接口就可以生成不同的图形。事实上,这种用法被称为“工厂模式”。
2。可以实现一个类只有一个对象。请看下面的代码
//Handler.java
public class Handler {
private Handler handler = null;
private Handler() {
/* set something here */
}
public static getHandler(/* arglist */) {
if (!handler)
handler = new Handler();
return handler;
}
public static void main(String args[]) {
Handler.getHandler();
}
}
当handlerw为空时,那么重新构造一个handler,然后返回;如果已经构造过了,那么就直接返回已经存在的handler。这种用法被称为“Singleton pattern". 如果直接使用构造函数来构造对象,那么你就无法控制生成的数量。在实际应用中,往往会做一些改变。比如使用一个具有一定容量的池,当需要构造一个对象而池的容量仍未满时,就构造一个新的对象,并放入池中,并把对象的状态设为“占用”状态;当需要构造一个对象而池的容量已满,则从池中选一个“空闲”状态的对象返回,并把对象的状态设为“占用”。当对象使用完后再回收到池中并把状态设为“空闲“。
这种模式的一个典型应用场景是:
在一个具有很多用户的web站点里,需要一个对象来单独处理一个连接,而每一个连接的时间比较短。如果每次连接都创建一个对象然后又很快销毁,那么创建和销毁对象的系统开销是很大的。这种时候可以使用对象池,这样就免去了创建和销毁对象的开销。
3。可以方便的拋出异常。请看下列代码:
public class Test {
public Test() {
double x = 1.0/0.0;
}
public static void main(String args[]) {
try {
Test test = new Test();
}catch (Exception e){
System.out.println(e.toString());
}
}
}
编译,执行,你会发现这个异常不会被捕捉,没有任何输出;即使尝试在构造函数中捕捉异常也不行。看下列代码:
public class Test {
public Test() {
try {
System.out.println("trying to throw an exception");
double x = 1.0/0.0;
} catch(Exception e) {
System.out.println("Exception captured");
}finally {
System.out.println("inside finally");
}
}
public static void main(String args[]) {
Test test = new Test();
}
}
编译,运行,结果为:
trying to throw an exception
inside finally
原因是JVM把构造函数产生的异常丢弃了。试想你正在使用一个第三方的类库提供的类,那个类提供一个共有的构造函数,它允许你通过参数构造一个类的对象,可是如果你的参数不合法,导致在构造函数中产生一个异常,那么你永远不知道具体发生了什么。当然如可以在每次构造对象时进行参数合法性检查,可是假设你要构造好多这样的对象??那将是一场灾难。这时可以通过把构造函数的访问级别设为私有,强迫类的使用者使用一个工厂函数来生成需要的对象,那么就可以在这个函数中统一的进行参数检查了。具体的代码就不写了,留给读者去实践吧!
从上面的分析我们可以知道私有构造函数的威力。需要注意的一点是,即使你的构造函数什么都不做,比如:
private Shape() {}
你仍然要显示的定义,因为如果你不定义,那么Java会自动为你生成一个空构造函数,而这个空构造函数是共有的。
分享到:
相关推荐
还有以下两个成员函数:一个用于初始化学生姓名、学号、性别和年龄的构造函数,一个用于输出学生信息的函数。编写一个主函数。声明一个学学生对象。然后调用成员函数在屏幕输出学生信息。 编程环境:vs2010,语言:...
主要介绍了Java面向对象类的定义,静态变量,成员变量,构造函数,封装与私有,this概念与用法,较为详细的分析了Java类的定义,静态变量,成员变量,构造函数,封装,私有等相关原理、用法及操作注意事项,需要的朋友...
PowerMock的核心功能在于其能够通过提供定制的类加载器和应用一些字节码操作技巧,实现对静态方法、构造方法、私有方法和final方法的模拟。例如,在进行单元测试时,有时候我们并不希望测试数据进入实际的数据库,...
HelloWorldApp.java 第一个用Java开发的应用程序。 firstApplet.java 第一个用Java开发的Applet小程序。 firstApplet.htm 用来装载Applet的网页文件 第2章 示例描述:本章介绍开发Java的基础语法知识。 ...
java 类 对象引用 对象 构造函数 抽象类和接口,图形解析 Car c = new Truck(); 注意:当一个类中有多个构造函数时,可以通过this关键字相互调用。根据参数的个数、类型,选择调用哪一个构造函数。 注意:当父类的...
构造函数是和类同名的函数,没有返回类型,构造函数不能在普通的程序里面调用,只有当这个类被应用new实例化的时候才会被运行。构造函数没有返回类型,实际上,构造函数返回的就是这个class本身。 类初始化时构造函数...
设计一个学生类Student,其中的属性有:学号stunum、姓名name、性别Gender、年龄age。方法包括:设置学号、姓名,取得性别、年龄。利用学生类,创建一个对象,描述自己的所有属性。
"分享一个在Java中反射获取私有构造函数、属性、方法" 我一直以为类的私有构造函数、属性、方法除了类自身其他类是无法访问的,前几天正好学习Spring框架,在学习Spring框架基础 Bean包时,写了一个简单的例子,类似...
13.子类不能继承父类的构造函数。( ) 14.重载的方法可以通过它们的返回值类型的不同来区分。( ) 16.在 Applet 的坐标系中,(0,0) 代表输出窗口左上角的象素点。( ) 18.构造函数的方法名可由编程人员任意命名。( ) 19...
给定一个C语言函数,要求实现在java类中进行调用。 45.如何获得数组的长度? 46.访问修饰符“public/private/protected/缺省的修饰符”的使用 47.用关键字final修饰一个类或者方法时,有何意义? 48.掌握类和...
不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 接口(interface)...
2.私有的构造函数(保证在该类外部,无法通过new的方式来创建对象实例) 3.公有的、静态的、访问该实例对象的方法 单例模式分为懒汉形和饿汉式 懒汉式: 应用刚启动的时候,并不创建实例,当外部调用该类的实例或者...
Kevvy-Reflect 高性能的java反射,适用于频繁调用的情况!! 概述 Kevvy-Reflect是一个非常小的Java库,它通过使用代码生成... ###公共构造函数调用: 在Oracle的Java 7u21服务器VM上生成。 用法 场反射 TestClass
它是一个库,允许在运行时访问非私有方法和构造函数的参数名称。 通常,此信息由编译器删除。 实际上,对于使用Java反射来检查方法的人们来说,诸如doSometing(mypkg.Person toMe)目前看起来像doSomething...
不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 接口(interface...
要使用它,请执行以下操作:在DAO实现(@Repository)中,创建一个私有字段EntityManager并通过构造函数注入对其进行分配。 在服务实现,构造函数注入中,向dao实现添加一个Qualifier。 spring data jpa...
本书是第II卷,以开发人员在项目开发中经常遇到的问题和必须掌握的技术为中心,介绍了应用Java进行桌面程序开发各个方面的知识和技巧,主要包括Java语法与面向对象技术、Java高级应用、窗体与控件应用、文件操作...