A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 huyang936 于 2015-2-5 00:37 编辑
  1. <p>package cn.itcast;
  2. /****************调用出错******************************************************************************/
  3. class Person {
  4. String name;//加static
  5. String department;
  6. int age;//加static
  7. int num = age;
  8. public Person()
  9. {
  10.   System.out.println(name+"::"+age);
  11. }
  12. public Person(String n) {
  13.   name = n;
  14. }

  15. public Person(String n, int a) {
  16.   name = n;
  17.   age = a;
  18. }

  19. public Person(String n, String d, int a) {
  20.   // 完成Person(String n, int a)的逻辑
  21.   this(name,age); //【【【此处调用出错】】】
  22.   department = d;
  23. }
  24. }




  25. /****************加static后,错误解除******************************************************************************/
  26. package cn.itcast;
  27. class Person {
  28. static String name;//加static
  29. String department;
  30. static int age;//加static
  31. int num = age;
  32. public Person()
  33. {
  34.   System.out.println(name+"::"+age);
  35. }
  36. public Person(String n) {
  37.   name = n;
  38. }

  39. public Person(String n, int a) {
  40.   name = n;
  41.   age = a;
  42. }

  43. public Person(String n, String d, int a) {
  44.   // 完成Person(String n, int a)的逻辑
  45.   this(name,age); //【【【问题解除】】】
  46.   department = d;
  47. }
  48. }

  49. </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, 下载次数: 28)

调用报错

调用报错

图片2.png (129.79 KB, 下载次数: 25)

错误解除

错误解除

评分

参与人数 1技术分 +1 收起 理由
黑妞~ + 1

查看全部评分

20 个回复

倒序浏览
我是这么理解的,加上static后,this(name,age); 这条语句接收的不是new对象的参数,而是类里面静态的name和age,而且默认值分别是null和0
回复 使用道具 举报
楼主加油
回复 使用道具 举报
{:3_53:}你的帖子让我又增加了对this的认识
回复 使用道具 举报
楼主,加油呀,赞
回复 使用道具 举报
学习了~~~~~~~~~
回复 使用道具 举报
还在纠结这个题。。。
回复 使用道具 举报
感谢分享,楼主加油!!!:lol
回复 使用道具 举报
加油啊!!!!
回复 使用道具 举报
加油!楼主!!
回复 使用道具 举报
kenfine 发表于 2015-2-3 22:52
我是这么理解的,加上static后,this(name,age); 这条语句接收的不是new对象的参数,而是类里面静态的name ...

这个问题最纠结的是:不加static,成员变量的默认初始化也优先于调用的构造函数初始化,所以,不加static,name和age中的值已经有值了null和0;那么问题来了,加static可以,不加问什么不行呢???
回复 使用道具 举报
我用的是eclipse开发做的,那里有显示哪一个和哪一个是一样的。我这么理解吧:如果用static 的话,this(name,age)用的是类中的类变量,而不加则用的是对象的变量。
回复 使用道具 举报
补充:加了static成员变量在类加载的时候就已经初始化了,而且优于对象出现,不依赖对象了,而构造函数的作用不是恰好就是创建对象使用的?
回复 使用道具 举报
kenfine 发表于 2015-2-4 21:55
我用的是eclipse开发做的,那里有显示哪一个和哪一个是一样的。我这么理解吧:如果用static 的话,this(nam ...

嗯 谢谢 回复 我刚刚在网上找了 这个 问题解释 你也可以看下(我修改了帖子)
回复 使用道具 举报
好贴,学习受教了!
回复 使用道具 举报
我看了你这个问题也是吓了一跳,为什么呢?给大家看两段代码:
  1. public Person(<font color="#ff0000">String n, String d,</font> int a) {
  2.   // 完成Person(String n, int a)的逻辑
  3. <font color="#ff0000">  this(name,age);</font> //【【【此处调用出错】】】
  4.   department = d;
  5. }
复制代码
  1.         Person1<font color="#ff0000">(int age,String name</font>,String depart)
  2.         {
  3. <font color="#ff0000">                this(age,name);</font>
  4.                 this.depart = depart;
  5.         }
复制代码
可以看到代码2片段中是没有错误的,为什么?因为此处的age和name是传进来的局部变量,而楼主的代码为什么错误,因为name和age是类的成员变量,类的普通成员变量是依托对象而存在,而静态成员变量是依托于类而存在。静态成员变量优先于构造函数存在。
现在解释为什么加static和不加static:
不加static:我们建立对象,调用三个参数的构造方法,但是在之前并没有age和name
加上static:成员变量优先于构造函数存在,类加载的时候也存在了,所以在构造的时候就没问题。

回复 使用道具 举报
邓士林 发表于 2015-2-5 09:00
我看了你这个问题也是吓了一跳,为什么呢?给大家看两段代码:可以看到代码2片段中是没有错误的,为什么? ...

嗯 谢谢回复分享
我当时的疑惑是这样的:
这个问题最纠结的是:不加static,成员变量的默认初始化也优先于调用的构造函数初始化,所以,不加static,name和age中的值已经有值了null和0
现在的理解:
虽然对象在加载过程中,成员变量的默认初始化是优先于所有构造方法的,但编译器不会这样理解,
这样做违背了使用构造器的初衷:
构造器就是用来初始化对象的成员变量的(在没有显式初始化之前更是这样),
即:在构造函数之前,该变量是不确定的,所以也就不能当作实参进行值传递了
这也只是我现在的理解,不对的地方请阁下不吝指教,呵呵
回复 使用道具 举报
感谢楼主分享
回复 使用道具 举报
huyang936 发表于 2015-2-4 21:24
这个问题最纠结的是:不加static,成员变量的默认初始化也优先于调用的构造函数初始化,所以,不加static ...

你的this(name,age) 不是调用的是构造函数Person(String n, int a),如果this(name,age)语句可以执行,那么久需要在属性name和age上加 static
回复 使用道具 举报
楼主加油!
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马