Thinking in java 4th edition的问题

CrySleeper 2009-12-02 09:17:53
Resuing classes那一章Initialization and class loading 小节
有个注释“The constructor is also a static method even though the static keyword is not explicit...”
这句话是不是有问题,constructor什么时候成了static method了?作者为了写那么厚的书是不是嗑了很多药,哈哈
...全文
276 28 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
feng_jyie 2009-12-03
  • 打赏
  • 举报
回复
晚上回去查一下再来
junjun1984 2009-12-03
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 zhuzhusany 的回复:]
肯定不对的嘛。。。
[/Quote]
你也混JAVA区的啊……
yang677888 2009-12-03
  • 打赏
  • 举报
回复
呵呵
zhuzhusany 2009-12-03
  • 打赏
  • 举报
回复
肯定不对的嘛。。。
bobo364 2009-12-03
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 myeclipse0123 的回复:]
是啊,楼主你确定是正版的?
[/Quote]

请不要搞笑,外国人写书的风格就是如此,很多带与自己的想法,虽说不太正确
CrySleeper 2009-12-03
  • 打赏
  • 举报
回复
怎么这么多人把constructor当作是了整个对象构造过程?
浮于表面莫非真是JAVA的硬伤?还是Thinking in java只是写给菜鸟看的?
baby1986 2009-12-03
  • 打赏
  • 举报
回复
由于构造方法与一般的方法不同,所以用常规方法的思路理解构造器肯定行不通的;
作者的意思可能是为了说明类成员的加载顺序;
如果把构造器当作静态的很多行为就好理解了,不用钻牛角尖吧!
zhuzhusany 2009-12-03
  • 打赏
  • 举报
回复
我觉得只能说construtor是类似static method的行为
但不能说它就是类的static method
因为
1.如果他是类的static method 那为什么不能直接通过类去调用?显然Test.Test();编译ERROR
2.如果它是static的它为什么会比静态块或者静态方法后执行?即使在他们之前声明
3.对于static的,他不是线程安全的,所有实例都共享static的,那么构造方法构造的实例需要主动考虑线程安全问题吗?
所以我认为construtor就是construtor
,不能说他就是类的方法
云上飞翔 2009-12-03
  • 打赏
  • 举报
回复
与22楼冲突了,打字发贴时,当时只看到楼层到了21楼。呵呵。。。。
怕打字。。。
云上飞翔 2009-12-03
  • 打赏
  • 举报
回复
唉。。。
前面都已说了:说构造器是static的方法,真正是胡说。为什么就不明白呢?

A a=new A();是怎么执行的?
是先在内存中创建了对象A(注意:此时已有了对象A,但空间还没有初始化),然后利用该对象的this来调用那个所谓的<init>()的隐含方法的。
是先有对象A,再自动调用其<init>()方法,这与调用static方法f(),没有对象就调用方法f()是完全不同的。
ZangXT 2009-12-03
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 shine333 的回复:]
我认为作者是对的,
A a = new A();
相当与调用了
A a = A. <init>();方法,只不过这个静态的方法名是" <init>",通过java代码是无法调用的,同样还有一个“ <cinit>”方法
[/Quote]
显然错误。
A a = new A();
是先调用new操作得到对象引用之后,才调用 <init>方法的。因为<init>需要隐含的this引用。

而static是不需要this引用的。

如果学过c++的话,会很容易理解:
A* a = new A;
new导致两个步骤:第一调用operator new操作符(这个操作符是static的),第二调用构造器。

所以关键问题是,可以认为是static的是分配内存操作,而不是构造方法

APOLLO_TS 2009-12-03
  • 打赏
  • 举报
回复
我没看过那本书,谁借我一本清晰的PDF看看?

LS说的也不少了。我也说一句。

任何类的构造方法在jvm中是加了super样式的实现的。最后:

public class Object {

private static native void registerNatives();
static {
registerNatives();
}
}

然后java使用了C语言等优先调用了初始化方法。即是你不写构造方法,JVM也默认加上一个,为什么?

实现构造方法,其实更像一个函数指针,指向了初始化部分。

哦!构造方法执行初始化部分,那为什么不这样写呢?

public Object() {
registerNatives();
}

我估计JDK今后会有内存优化的动作,目前不就有premain()方法观测内存么!

估计今后为了扩展,构造方法会更像一个引导地址。

以上纯属本人胡说八道。大家就当我忽悠人。
dracularking 2009-12-03
  • 打赏
  • 举报
回复
更正:可见访问构造方法前执行了静态成员初始化(static initialization)
dracularking 2009-12-03
  • 打赏
  • 举报
回复
现在将原文中几句话组合起来再看一遍:
class code is loaded at the point of first use.
The point of first use is also where the static initialization takes place.
a class is first loaded when any one of its static members is accessed.
由以上三句得出推论:when any one of its static members is accessed static initialization takes place.


public class Test {
private int k = printInit("Beetle.k initialized");
int j;

public Test() {
System.out.println("k = " + k);
System.out.println("j = " + j);
}

private static int x2 = printInit("static Beetle.x2 initialized");

static int printInit(String s) {
System.out.println(s);
return 47;
}

public static void main(String[] args) {
System.out.println("Beetle constructor");
new Test();
}
}

运行结果:
static Beetle.x2 initialized
Beetle constructor
Beetle.k initialized
k = 47
j = 0

可见访问构造方法时执行了静态区块初始化,也就证明了构造方法是one of its static members,“静态”!
heartraid86 2009-12-03
  • 打赏
  • 举报
回复
我也这么认为,在没有创建对象前调用的方法,是非静态方法能做到吗?

Thinking in Java的作者这么考虑说的过去。我觉的没什么疑问的?
shine333 2009-12-03
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 army27 的回复:]
construtor是静态函数,当调用class construtor函数的时候,执行初始化的工作,把对象生成放到堆空间里,反过来说,如果不是静态函数,怎么来生成对象呢?
[/Quote]
就是啊,java的函数从static这个角度而言,就两种,static/non-static,constructor显然是前者
西北地的风 2009-12-03
  • 打赏
  • 举报
回复
construtor是静态函数,当调用class construtor函数的时候,执行初始化的工作,把对象生成放到堆空间里,反过来说,如果不是静态函数,怎么来生成对象呢?
shine333 2009-12-03
  • 打赏
  • 举报
回复
我认为作者是对的,
A a = new A();
相当与调用了
A a = A.<init>();方法,只不过这个静态的方法名是"<init>",通过java代码是无法调用的,同样还有一个“<cinit>”方法,对应static {} 代码段
具体可以看下例子:
public class Test {

static {
RuntimeException ex = new RuntimeException();
ex.fillInStackTrace();
ex.printStackTrace();
}

public Test() {
throw new RuntimeException();
}

public static void main(String[] args) throws Exception {
new Test();
}

}

zhuzhusany 2009-12-03
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 zhuzhusany 的回复:]
肯定不对的嘛。。。
[/Quote]
恩。。。不好混,高手太多哈哈
dracularking 2009-12-03
  • 打赏
  • 举报
回复
我想从某一个侧面也许能说明一定问题,对于某一个类中的非静态xxx方法,如果直接在main方法中调用,在eclipse中会得到如下提示:
Cannot make a static reference to the non-static method xxx() from the type Test
但如果构造方法却能直接使用,没有问题,就像静态方法一样。
但是访问静态类成员时类被加载和构造方法之间有什么直接联系作者却貌似没有直接点明。
a class is first loaded when any one of its static members is accessed.
加载更多回复(8)

62,634

社区成员

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

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