请教一个内部类的问题: new A().super()

wtfeng 2004-05-06 01:30:17
请问对于
class A{
class B{
B(){}
}
}
class C extends A.B
{
public static void main(String args[]){
new A().super();
C c=new C();
}
中的 new A().super() 应如何理解?
我试过它等价于 (new A()).super()
但我觉得这样得不到内部类B的实例.
...全文
131 24 点赞 打赏 收藏 举报
写回复
24 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
zxs790501 2004-05-14
理解!

楼上的已经解释得很明白了
  • 打赏
  • 举报
回复
raimundo 2004-05-14
你的问题归根到底是要理解inner class的含义,一个非static的inner class是instance作用域的,也就是必须在一个实例的范围内生效,因此初始化一个非static的inner class就必须指明它存在的instance域。
如果是要继承一个inner class,那么只能在构造子里指明它的Instance域,如下的代码也是可以的:
public class Outer {
class Inner {

}
}

class Test extends Outer.Inner {
static Outer outer = new Outer();
Test(){
outer.super();
}
}
从一个static的实例去调super不是更奇怪?其实不过是通过这种语法指定inner class的instance域而已,没什么奇怪的
  • 打赏
  • 举报
回复
raimundo 2004-05-14
to wtfeng(独孤九剑)

new A().super()等价于(new A()).super()

new A().super()
相当于
A.B inner = new A().new B();

(new A()).super()
相当于
A.B inner = (new A()).new B();

因为B是非static的内部类,所以初始化的时候必须要要和一个外部类(也就是A)的实例关联,因此,如果定义

class A {
class B{
}
}
那么通过反射你可以发现,B()这个无参构造子的参数列表长度并不是0而是1,而这个隐含的参数类型的class就是A,也就是说它需要一个a的实例,同样下面的程序中B()的参数是两个而不是1个,分别是A.class, int.class
class A {
class B{
B(int x) {
}
}
}
所以a.super(),实际上是super(a),但是由于内部类的outer实例是隐式约定,所以才使用类似a.super()的语法
  • 打赏
  • 举报
回复
wtfeng 2004-05-14
我们假设可以的话,
a.super()应该如何理解?
  • 打赏
  • 举报
回复
maowu 2004-05-14
不能编译了是因为调用super()这种父类的构造方法必须要在自己的构造方法的第一行.
所以
A a=new A();
a.super(); //这里变成第二行了.
是不合法的.
  • 打赏
  • 举报
回复
wtfeng 2004-05-14
!!!!!!!!!!!本人所问问题强调的是:
new A().super()等价于(new A()).super()
大家难道不觉得这个很特别吗?
但当你折开时:
A a=new A();
a.super();
这样就不能通过编译了!
  • 打赏
  • 举报
回复
hppby 2004-05-14
MARK
  • 打赏
  • 举报
回复
raimundo 2004-05-14
赫赫,我在学java以前有六年C++经验,我刚看java的时候也老往底层想,其实java是一门很优雅的语言(比起C++,犹如法语、拉丁文之于英语),除了特别特殊的应用,比如AOP weaver之类的,是不会用到特别底层的东西的。
  • 打赏
  • 举报
回复
wtfeng 2004-05-14
感谢raimundo颇为详尽的解答!
由于最近经常接触汇编的缘故,我现在头脑满是java之对应于汇编代码的仿真实现,有些问题始终觉得是回到汇编的实现上才会真相大白的,否则纯粹就概念上理解有时也很费劲.最近也看深入浅出mfc,我想c++与java在类上面的问题应该是相似的.但一般的方法很难捕捉到java实现的底层内容.还是先精通C++吧!
  • 打赏
  • 举报
回复
raimundo 2004-05-13
如果改为
class Outer {
class Inner {
Inner(int x) {
}
}
}
则在Test里就是
class Test extends Outer.Inner {
Test(int x) {
new Outer().super(x);
}
}
其中的new Outer().super(x)在其他地方就是

Outer o = new Outer();
Outer.Inner inner = o.new Inner(5);

因为Test是Outer.Inner的子类,所以必须是在构造函数里调用new Outer().super(5);
这里的.super不是指的Outer的super,而是指得Test的super,也就是Outer.Inner
  • 打赏
  • 举报
回复
raimundo 2004-05-13
嘿嘿,调通了,这个没什么可不好理解的

class Outer {
class Inner {
}
}

我们使用Inner的时候

Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();

所以可以看到inner是需要一个Outer的实例才能new的,所以当有一个类

class Test extends Outer.Inner {
Test() {
需要一个Outer的实例,并且需要调用Inner的构造函数
}
}

所以new Outer().super() == outer.new

A a=new A();
a.super();
不行是因为super只能是构造第一行
  • 打赏
  • 举报
回复
raimundo 2004-05-13
?????
这个东西能运行吗?
谁给我一个能运行得版本?我一执行就是java.lang.NoClassDefFoundError
  • 打赏
  • 举报
回复
wtfeng 2004-05-13
new A() 当然就是先调用A的构造方法了,然后返回一个引用,这个引用有super()方法吗?
.super()为什么可以调用B的构造方法?
为什么不能以
A a=new A();
a.super();
来代替
new A().super();
既然
(new A()).super()等价于new A().super();
编译器在后面做了些什么?
这个语法是不是有点特殊?
  • 打赏
  • 举报
回复
let5flying 2004-05-11
应该是说明用A的构造方法来构造C吧
如果不加的话,应该是默认调用父类的super() 即A和B的

我也是刚学,不知道对不对
  • 打赏
  • 举报
回复
programer23 2004-05-09
super是调用父类的构造函数,如果你想调用A的B。
这样:class A{
class B{
B(){}
public void example()
{system.out.println("example");}
}
public static B getB()
{
rerurn new B();
}
}

class C extends A.B
{
public static void main(String args[]){
A.getB().example();
C c=new C();
}

  • 打赏
  • 举报
回复
lancelot_yao 2004-05-09
new A().super();
这一句语法不对
  • 打赏
  • 举报
回复
watch!
  • 打赏
  • 举报
回复
nwsl 2004-05-09
想调用A.B的构造方法,必须先造A的对象,不是吗?所以先new了呀,这只是我的一种感性认识。
  • 打赏
  • 举报
回复
nwsl 2004-05-09
即使是new了A对象,也只是C的一个变量而已。super指的依然是C的super。
  • 打赏
  • 举报
回复
pirateRocy 2004-05-09
不明白楼主想要干什么?
当然这些语法本身没有问题,但是没有具体意义啊。
  • 打赏
  • 举报
回复
加载更多回复
相关推荐
发帖
Java SE
加入

6.2w+

社区成员

Java 2 Standard Edition
申请成为版主
帖子事件
创建了帖子
2004-05-06 01:30
社区公告
暂无公告