新手请教个问题,关于JAVA核心技术例程

TheSaviour 2015-06-27 02:09:31
ConstructorTest.java
……
// object initialization block
{
id = nextId;
nextId++;
}
静态初始化块中,nextId自加一,这时应该已经比id大了1吧?
……

下面的构造函数里,为什么nextId还是和id相等呢?
……
public Employee(double s)
{
// calls the Employee(String, double) constructor
this("Employee #" + nextId, s);
}
……
...全文
608 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
TheSaviour 2015-07-15
  • 打赏
  • 举报
回复
给作者发了个e,也没理会,呵呵…… 结了吧
chen870201 2015-06-30
  • 打赏
  • 举报
回复
感觉好绕
scmod 2015-06-30
  • 打赏
  • 举报
回复
引用 17 楼 TheSaviour 的回复:
[quote=引用 15 楼 scmod 的回复:] 哦...貌似this()这样调用比较神奇... 会在调用的this代表的构造方法前执行非静态初始化块而不是在调用this的这个构造方法前调用 老神奇了~~
既然非晶态初始化块先运行了,为什么 this("Employee #" + nextId, s); 的nextId和id还一样呢?[/quote] 我的意思是调用this调用的构造方法前执行非静态那块 也就是说this("Employee #" + nextId, s);中Employee #" + nextId的时候nextId并没有自增过 这句执行完把Employee #" + nextId这个字符串传给 public Employee(String n, double s)这个构造方法时候非静态块才执行 nextId这时候才自增的不过已经没什么卵用的并不影响前面生成的那个字符串 就是和9楼说的一个意思 一般我都以为非静态必定是在构造方法调用前执行的,原来是错的~~
tony4geek 2015-06-30
  • 打赏
  • 举报
回复
你看看类的加载顺序, 或者代码块里面pring 看看。
TheSaviour 2015-06-30
  • 打赏
  • 举报
回复
引用 15 楼 scmod 的回复:
哦...貌似this()这样调用比较神奇... 会在调用的this代表的构造方法前执行非静态初始化块而不是在调用this的这个构造方法前调用 老神奇了~~
既然非晶态初始化块先运行了,为什么 this("Employee #" + nextId, s); 的nextId和id还一样呢?
scmod 2015-06-29
  • 打赏
  • 举报
回复
哦...貌似this()这样调用比较神奇... 会在调用的this代表的构造方法前执行非静态初始化块而不是在调用this的这个构造方法前调用 老神奇了~~
scmod 2015-06-29
  • 打赏
  • 举报
回复
我怎么记得非静态初始化也是在构造方法之前运行的....
TheSaviour 2015-06-29
  • 打赏
  • 举报
回复
引用 12 楼 qq118194716 的回复:
注意区分 静态初始化块 和 非静态初始化块
你的意思是: { id = nextId; nextId++; } 这个是非静态初始化块,是在构造函数之后调用,而 static { Random generator = new Random(); // set nextId to a random number between 0 and 9999 nextId = generator.nextInt(10000); } 这个才是静态初始化块,最先运行,只运行一次?
god_chance 2015-06-28
  • 打赏
  • 举报
回复
引用 5楼啊ooo 的回复:
[quote=引用 4 楼 u014165119 的回复:] 因为他们本来就是同一个对象,id引用的是nextId,所以nextId值改变之后,id和nextId还是相等的。 id=newxtId;并不是赋值,而是把一个引用(类似c/c++的指针)指向nextId对象。
sorry,我错了[/quote]
飏飏一蝶 2015-06-28
  • 打赏
  • 举报
回复
先运行这句 this("Employee #" + nextId, s); 也就是运行了其中的"Employee #" + nextId这句 也就是在运行对象初始化块之前,就已经用nextId来说明了将要生成对象的属性
飏飏一蝶 2015-06-28
  • 打赏
  • 举报
回复

// object initialization block
   {
      id = nextId;
      nextId++;
   }

   public Employee(double s)
   {
      // calls the Employee(String, double) constructor
      this("Employee #" + nextId, s);
   }
理解这个问题的关键在于运行的顺序和时机 public Employee(double s)运行时,并没有立即运行对象初始化块 而是先运行 this("Employee #" + nextId, s); 直到这个时候,才引起对象初始化块的执行 因此此时的"Employee #" + nextId中的nextID记录的是未增1前的值 因为String是不可变类,传入的"Employee #" + nextId是字符串,其中的nextId一旦确定不再改变 所以这里用nextId,在构造对象前,传入下个对象应该生成的ID,来说明将要生成对象的真正属性 我只想说,技巧性太强了,我是写不出的....
飏飏一蝶 2015-06-28
  • 打赏
  • 举报
回复
引用 11 楼 TheSaviour 的回复:
[quote=引用 9楼飏飏一蝶 的回复:]

// object initialization block
   {
      id = nextId;
      nextId++;
   }

   public Employee(double s)
   {
      // calls the Employee(String, double) constructor
      this("Employee #" + nextId, s);
   }
理解这个问题的关键在于运行的顺序和时机 public Employee(double s)运行时,并没有立即运行对象初始化块 而是先运行 this("Employee #" + nextId, s); 直到这个时候,才引起对象初始化块的执行 因此此时的"Employee #" + nextId中的nextID记录的是未增1前的值 因为String是不可变类,传入的"Employee #" + nextId是字符串,其中的nextId一旦确定不再改变 所以这里用nextId,在构造对象前,传入下个对象应该生成的ID,来说明将要生成对象的真正属性 我只想说,技巧性太强了,我是写不出的....
但是书里这一章,专门强调了静态初始化块是在构造函数之前运行的。[/quote] 注意区分 静态初始化块 和 非静态初始化块
TheSaviour 2015-06-28
  • 打赏
  • 举报
回复
引用 9楼飏飏一蝶 的回复:

// object initialization block
   {
      id = nextId;
      nextId++;
   }

   public Employee(double s)
   {
      // calls the Employee(String, double) constructor
      this("Employee #" + nextId, s);
   }
理解这个问题的关键在于运行的顺序和时机 public Employee(double s)运行时,并没有立即运行对象初始化块 而是先运行 this("Employee #" + nextId, s); 直到这个时候,才引起对象初始化块的执行 因此此时的"Employee #" + nextId中的nextID记录的是未增1前的值 因为String是不可变类,传入的"Employee #" + nextId是字符串,其中的nextId一旦确定不再改变 所以这里用nextId,在构造对象前,传入下个对象应该生成的ID,来说明将要生成对象的真正属性 我只想说,技巧性太强了,我是写不出的....
但是书里这一章,专门强调了静态初始化块是在构造函数之前运行的。
TheSaviour 2015-06-27
  • 打赏
  • 举报
回复
运行结果: name=Harry,id=1539,salary=40000.0 name=Employee #1540,id=1540,salary=60000.0 name=,id=1541,salary=0.0 nextId初值是随机产生,每次运行结果不太一样,但是第二行,说明nextId和id是相等的。
TheSaviour 2015-06-27
  • 打赏
  • 举报
回复
《Java核心技术 卷一》第四章的例程 全部程序如下: import java.util.Random; /** * This program demonstrates object construction. * @version 1.01 2004-02-19 * @author Cay Horstmann */ public class ConstructorTest { public static void main(String[] args) { // fill the staff array with three Employee objects Employee[] staff = new Employee[3]; staff[0] = new Employee("Harry", 40000); staff[1] = new Employee(60000); staff[2] = new Employee(); // print out information about all Employee objects for (Employee e : staff) System.out.println("name=" + e.getName() + ",id=" + e.getId() + ",salary=" + e.getSalary()); } } class Employee { private static int nextId; private int id; private String name = ""; // instance field initialization private double salary; // static initialization block static { Random generator = new Random(); // set nextId to a random number between 0 and 9999 nextId = generator.nextInt(10000); } // object initialization block { id = nextId; nextId++; } // three overloaded constructors public Employee(String n, double s) { name = n; salary = s; } public Employee(double s) { // calls the Employee(String, double) constructor this("Employee #" + nextId, s); } // the default constructor public Employee() { // name initialized to ""--see above // salary not explicitly set--initialized to 0 // id initialized in initialization block } public String getName() { return name; } public double getSalary() { return salary; } public int getId() { return id; } }
StoneHui_ 2015-06-27
  • 打赏
  • 举报
回复
引用 4 楼 u014165119 的回复:
因为他们本来就是同一个对象,id引用的是nextId,所以nextId值改变之后,id和nextId还是相等的。 id=newxtId;并不是赋值,而是把一个引用(类似c/c++的指针)指向nextId对象。
sorry,我错了
StoneHui_ 2015-06-27
  • 打赏
  • 举报
回复
因为他们本来就是同一个对象,id引用的是nextId,所以nextId值改变之后,id和nextId还是相等的。 id=newxtId;并不是赋值,而是把一个引用(类似c/c++的指针)指向nextId对象。
alan19931103 2015-06-27
  • 打赏
  • 举报
回复
这什么都看不出来,代码多一些
X元素 2015-06-27
  • 打赏
  • 举报
回复
整个代码贴出来看一下
qq_29319315 2015-06-27
  • 打赏
  • 举报
回复
ConstructorTest.java
public Employee(double s)
两个是一个类还是两个,两个什么关系完全看不出来。贴详细点。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧