黑马程序员技术交流社区
标题: 基础班第二次考试选择题(关于构造函数调用的理解) [打印本页]
作者: huyang936    时间: 2015-2-3 22:14
标题: 基础班第二次考试选择题(关于构造函数调用的理解)
 本帖最后由 huyang936 于 2015-2-5 00:37 编辑 
- <p>package cn.itcast;
 
- /****************调用出错******************************************************************************/
 
- class Person {
 
-  String name;//加static
 
-  String department;
 
-  int age;//加static
 
-  int num = age;
 
-  public Person()
 
-  {
 
-   System.out.println(name+"::"+age);
 
-  }
 
-  public Person(String n) {
 
-   name = n;
 
-  }
 
 
-  public Person(String n, int a) {
 
-   name = n;
 
-   age = a;
 
-  }
 
 
-  public Person(String n, String d, int a) {
 
-   // 完成Person(String n, int a)的逻辑
 
-   this(name,age); //【【【此处调用出错】】】
 
-   department = d;
 
-  }
 
- }
 
 
 
 
 
- /****************加static后,错误解除******************************************************************************/
 
- package cn.itcast;
 
- class Person {
 
-  static String name;//加static
 
-  String department;
 
-  static int age;//加static
 
-  int num = age;
 
-  public Person()
 
-  {
 
-   System.out.println(name+"::"+age);
 
-  }
 
-  public Person(String n) {
 
-   name = n;
 
-  }
 
 
-  public Person(String n, int a) {
 
-   name = n;
 
-   age = a;
 
-  }
 
 
-  public Person(String n, String d, int a) {
 
-   // 完成Person(String n, int a)的逻辑
 
-   this(name,age); //【【【问题解除】】】
 
-   department = d;
 
-  }
 
- }
 
 
- </p>
 
第23道选择题:
1. 给出下面的不完整的类代码
  class Person {
    String name, department;
    int age;
    public Person(String n){ name = n; }
    public Person(String n, int a){ name = n; age = a; }
    public Person(String n, String d, int a) {
      // 完成Person(String n, int a)的逻辑
      department = d;
    }
  }
  下面的哪些表达式可以加到构造方法中的注释处? (   )
A. Person(n,a);
B. this(Person(n,a)); //构造函数的名字不能当方法名调用;
C. this(n,a);
D. this(name,age); //构造方法的参数也不能直接传实例变量名
D选项:“构造方法的参数也不能直接传实例变量名”:
如下图测试的那样,加static后就能使用呀,这个到底是怎么理解的呢???求解释!!!
****************************************************************************************************************************************
晚上回来又看了看这个问题,在网上找到了我认为合理的解释,大家不妨也看下
问题原因:
Cannot refer to an instance field name while explicitly invoking a constructor
明确调用一个构造器的时候不能引用类的一个实例域
原因分析:
全都没讲到点子上。报错这和final没有任何关系。举个列子
 
public int i=1; 
public MyThing(){ 
   super(i); 
} 
原因很简单,我们假如可以通过编译器。我问一个问题,调用构造器是干什么的? 
大家都知道,创建一个对象并初始化对象中的数据域。红色字体很重要,在上面的列子中new MyThing()的作用就是为了初始化这个对象的数据域i,试问在没有通过构造器初始化之前,i的值是不确定的。我们怎么能使用一个不确定的i值来初始化对象。 
打个比方:我们去银行取5元钱,但是必须首先交5块钱手续费(也就是首先明确初始化)。我能不能给银行的人说:你把5元先取给我,然后我再把这钱给你交手续费呢??? 
当然例子不是很恰当,但说的意思差不多。总之,必须要先明确初始化实例域,才能创建好对象,进而才能使用对象的数据域。在没有实例化之前就想使用他,就像没有取出5元钱就想先用这钱一样,不可能。
public int i=1; 
public MyThing(int j){ 
   super(j); 
} 
上面的代码就可以,为什么,因为编译器知道,你如果想构造这个对象,必须传过来一个确定的值来初始化。
- 
报错.png
(128.22 KB, 下载次数: 68)
 
 调用报错 
- 
图片2.png
(129.79 KB, 下载次数: 58)
 
 错误解除 
作者: kenfine    时间: 2015-2-3 22:52
我是这么理解的,加上static后,this(name,age); 这条语句接收的不是new对象的参数,而是类里面静态的name和age,而且默认值分别是null和0
作者: 小鹏_sJQBO    时间: 2015-2-3 22:53
楼主加油
作者: kenfine    时间: 2015-2-3 22:54
{:3_53:}你的帖子让我又增加了对this的认识
作者: 466273082    时间: 2015-2-3 23:14
楼主,加油呀,赞
作者: Novice.Jin    时间: 2015-2-3 23:56
学习了~~~~~~~~~
作者: 会飞d猪    时间: 2015-2-4 07:14
还在纠结这个题。。。
作者: 白衣布士    时间: 2015-2-4 12:38
感谢分享,楼主加油!!!:lol
作者: yanqiuqiu    时间: 2015-2-4 13:12
加油啊!!!!
作者: x1071765330    时间: 2015-2-4 13:14
加油!楼主!!
作者: huyang936    时间: 2015-2-4 21:24
这个问题最纠结的是:不加static,成员变量的默认初始化也优先于调用的构造函数初始化,所以,不加static,name和age中的值已经有值了null和0;那么问题来了,加static可以,不加问什么不行呢???
作者: kenfine    时间: 2015-2-4 21:55
我用的是eclipse开发做的,那里有显示哪一个和哪一个是一样的。我这么理解吧:如果用static 的话,this(name,age)用的是类中的类变量,而不加则用的是对象的变量。
作者: kenfine    时间: 2015-2-4 21:59
补充:加了static成员变量在类加载的时候就已经初始化了,而且优于对象出现,不依赖对象了,而构造函数的作用不是恰好就是创建对象使用的?
作者: huyang936    时间: 2015-2-5 00:29
嗯 谢谢 回复 我刚刚在网上找了 这个 问题解释 你也可以看下(我修改了帖子)
作者: clairetoto2012    时间: 2015-2-5 07:24
好贴,学习受教了!
作者: 邓士林    时间: 2015-2-5 09:00
我看了你这个问题也是吓了一跳,为什么呢?给大家看两段代码:- public Person(<font color="#ff0000">String n, String d,</font> int a) {
 
-   // 完成Person(String n, int a)的逻辑
 
- <font color="#ff0000">  this(name,age);</font> //【【【此处调用出错】】】
 
-   department = d;
 
- }
-         Person1<font color="#ff0000">(int age,String name</font>,String depart)
 
-         {
 
- <font color="#ff0000">                this(age,name);</font>
 
-                 this.depart = depart;
 
-         }
现在解释为什么加static和不加static:
不加static:我们建立对象,调用三个参数的构造方法,但是在之前并没有age和name
加上static:成员变量优先于构造函数存在,类加载的时候也存在了,所以在构造的时候就没问题。
作者: huyang936    时间: 2015-2-5 18:54
嗯 谢谢回复分享
我当时的疑惑是这样的:
这个问题最纠结的是:不加static,成员变量的默认初始化也优先于调用的构造函数初始化,所以,不加static,name和age中的值已经有值了null和0
现在的理解:
虽然对象在加载过程中,成员变量的默认初始化是优先于所有构造方法的,但编译器不会这样理解,
这样做违背了使用构造器的初衷:
构造器就是用来初始化对象的成员变量的(在没有显式初始化之前更是这样),
即:在构造函数之前,该变量是不确定的,所以也就不能当作实参进行值传递了
这也只是我现在的理解,不对的地方请阁下不吝指教,呵呵
作者: 朋好友    时间: 2015-2-5 20:35
感谢楼主分享
作者: 小马范    时间: 2015-2-5 21:11
你的this(name,age) 不是调用的是构造函数Person(String n, int a),如果this(name,age)语句可以执行,那么久需要在属性name和age上加 static
作者: 沌沌愚人心    时间: 2015-2-5 23:15
楼主加油!
作者: liuka    时间: 2015-2-7 08:53
受教受教!
| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |