java构造函数及初始化

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

示例 4: class One {
One(String str) {
System.out.println(str); } }
class Two {
One one_1 = new One("one-1"); One one_2 = new One("one-2"); static One one_3 = new One("one-3"); Two(String str) {
初始化的顺序包括构造方法调用的顺序如下: 1.主类的静态成员首先初始化。 2.主类的超类的构造方法按照从最高到最低的顺序被调用。 3.主类的非静态对象(变量)初始化。 4.调用主类的构造方法。
在一个构造方法中只能调用一次其它的构造方法,并且调用构造方法的语句必须是第 一条语句。
深度理解 JAVA 本身的构造器及子父类构造方法的初始化顺序
System.out.println(str); } }
class Two {
One one_1 = new One("one-1"); One one_2 = new One("one-2"); static One one_3 = new One("one-3"); Two(String str) {
示例 2:
class SuperClass {
SuperClass(String str) {
System.out.println("Super with a string."); } }
public class SubClass extends SuperClass {
SubClass(String str) {
输出结果: Test main() start... one-2 one-3 Two.i = 0
不仅第 1 次创建对象时,类中所有的静态变量要初始化,第 1 次访问类中的静态变量 (没有创建对象)时,该类中所有的静态变量也要按照它们在类中排列的顺序初始化。
综上所述:
在创建对象时,对象所在类的所有数据成员会首先进行初始化,如果其中的成员变量有 对象,那么它们也会按照顺序执行初始化工作。在所有类成员初始化完成后,才调用对象所 在类的构造方法创建对象。构造方法作用就是初始化。
示例 1:
class SuperClass
{
SuperClass()
{
System.out.println("SuperClass constructor");
}
}
public class SubClass extends SuperClass {
SubClass() {
System.out.println("SubClass constructor"); } public static void main(String[] args) {
System.out.println(str); } }
public class Test {
public static void main(String[] args) {
System.out.println("Test main() start..."); Two two_1 = new Two("two-1"); System.out.println("------------"); Two two_2 = new Two("two-2"); } }
public class MyTest { int i; String s; public MyTest() {
System.out.println("调用无参构造函数"); } public MyTest(int i) {
this.i=i; System.out.println("调用单参函数,而且i="+i); } public MyTest(int i,String s) { this.i=i; this.s=s; System.out.println("调用双参函数,而且i="+i+", s="+s); } public static void main(String []args) { MyTest t1=new MyTest(); MyTest t2=new MyTest(2); MyTest t3=new MyTest(3,"Hello"); } }
Java 构造函数
在 Java 中,构造函数的使用比较简单,但不注意也很容易出现问题。而一旦有了问题, 又不好排查,结合个人短期经验,现总结如下。
首先,构造函数具有以下几个特点: 1) 构造函数名与类名相同; 2) 构造函数不返回任何值,也没有返回类型; 3) 每一类可以有零个或多个构造方法; 4) 构造方法在创建对象时自动执行,一般不用显示地直接调用。 其次,就上面几个需要说明的特点进一步进行解释: 特点一:构造函数名与类名相同。这个很简单,只要知道 Java 语言是区分大小写即可; 特点二:这一特点需要说明,并加以强调。构造函数不返回任何值,也没有返回类型, 因此在构造函数前面不可添加各种基本数据类型,也不可添加引用类型。关键问题是,既然 构造函数不返回任何值,部分人很可能会在构造函数前面加上 void 关键字,这正是问题所 在。虽然没有返回类型,而且 void 也表示不返回任何值,但在构造函数前面最好不要添加 void 关键字。如果构造函数是无参的,编译没有问题,否则,则会有错误。例如下例所示:
第 2 种解决方法实际上是指定编译器不要寻找父类的默认构造方法,而是去寻找带一 个字符串为参数的构造方法。
下面介绍对象的初始化顺序问题。
示例 3:
class One {
One(String str) {
System.out.println(str); } }
class Two {
One one_1 = new One("one-1"); One one_2 = new One("one-2"); One one_3 = new One("one-3");
输出结果:
Test main() start... one-1 one-2 one-3 two
在 main()方法中实例化了一个 Two 类的对象。但程序在初始化 Two 类的对象时,并非 先调用 Two 类的构造方法,而是先初始化 Two 类的成员变量。这里 Two 类有 3 个成员变 量,它们都是 One 类的对象,所以要先调用 3 次 One 类的相应的构造方法。最后在初始 化 Two 类的对象。
System.out.println(str); } } public class Test { public static void main(String[] args) {
System.out.println("Test main() start..."); System.out.println("Two.i = " + Two.i); } }
System.out.println(str); } }
public class Test {
static Two two_3 = new Two("two-3"); public static void main(String[] args) {
System.out.println("Test main() start..."); Two two_1 = new Two("two-1"); System.out.println("------------"); Two two_2 = new Two("two-2"); } }
SubClass sub = new SubClass(); } }
输出结果:
SuperClass constructor SubClass constructor
在子类中只实例化了一个子类对象。从输出结果上看,程序并不是一开始就运行自己的 构造方法,而是先运行其父类的默认构造方法。注意:程序自动调用其父类的默认构造方法。
功能和作用的不同:
构造器是为了创建一个类的实例。这个过程也可以在创建一个对象的时候用到:Platypus p1 = new Platypus(); 相反,方法的作用是为了执行 java 代码。
特点四:构造方法在创建对象时自动执行,一般不用显示地直接调用。构造函数的作用 是对类的成员变量进行初始化操作,因此都是在创建类的对象是自动执行。
JAVA 技术专题综述 之 构造方法篇
类的继承机制使得子类可以使用父类的功能(即代码),并且子类也具有父类的类型。 下面介绍类在继承关系上的初始化的顺序问题。
示例 6: class One {
One(String str) {
System.out.println(str); } }
class Two {
static int i = 0; One one_1 = new One("one-1"); static One one_2 = new One("one-2"); static One one_3 = new One("one-3"); Two(String str) {
输出结果:
Test main() start... one-3 one-1 one-2 two-1 -----------one-1 one-2 two-2
如果一个类中有静态对象,那么它会在非静态对象前初始化,但只初始化一次。非静 态对象每次调用时都要初始化。
示例 5:
class One {
One(String str) {
System.out.println("Sub with a string."); } public static void main(String[] args) {
SubClass sub = new SubClass("sub"); } }
在 JDK 下编译此程序不能成功。正如上例中说的:程序在初始化子类时先要寻找其父 类的默认构造方法,结果没找到,那么编译自然不能通过。
输出结果: one-3 one-1 one-2 two-3 Test main() start... one-1 one-2 two-1 -----------one-1
one-2 two-2
程序中主类的静态变量会在 main()方法执行Hale Waihona Puke Baidu初始化。结果中只输出了一次 one-3,这 也说明:如果一个类中有静态对象,那么它会在非静态对象前初始化,但只初始化一次。非 静态对象每次调用时都要初始化。
静态对象(变量)在非静态对象前初始化。静态对象(变量)只初始化一次,再次调用 就不初始化了,但非静态对象在每次调用时都要初始化。
程序中的主类的静态变量会在 main()方法执行前进行初始化工作。 不仅第 1 次创建对象时,类中所有的静态变量要初始化,第 1 次访问类中的静态变量 (没有创建对象)时,该类中所有的静态变量也要按照它们在类中排列的顺序初始化。
在上例中,三个构造函数进行了重载,这时,在构造函数的前面不可添加 void 关键字, 否则会有编译错误。
特点三:每一类可以有零个或多个构造方法。如果类没有构造函数,编译器会自动添加 默认的无参构造函数,当调用默认的构造函数时,就会利用构造函数为类的成员变量进行初 始化,当然不同的类型其默认的初始值不同。一旦用户定义了构造函数,则不会产生默认 的构造函数。当有多个构造函数时,系统会根据产生对象时,所带参数的不同而选择调用不 同的构造函数。
Two(String str) {
System.out.println(str); } }
public class Test {
public static void main(String[] args) {
System.out.println("Test main() start..."); Two two = new Two("two"); } }
解决这个问题有两个办法: 1.在父类中增加一个默认构造方法。 2.在子类的构造方法中增加一条语句:super(str); 且必须在第一句。
这两种方法都能使此程序通过编译,但就本程序来说运行结果却不相同。
第 1 种方法的运行结果是: Sub with a string. 第 2 种方法的运行结果是: Super with a string. Sub with a string.
相关文档
最新文档