静态方法中调用内部类的问题

wolfkoala 2011-06-16 04:09:14
package innerclass;

public class Parcel2{

class Contents {
private int i = 11;
public int value() {return i;}
}

class Destination {
private String label;
Destination(String whereTo){
label = whereTo;
}
String readLabel() {return label;}
}

public Destination to(String s){
return new Destination(s);
}

public Contents contents() {
return new Contents();
}

public void ship (String dest){
Contents c = contents();
Destination d = to(dest);
System.out.println(d.readLabel());
}

public static void main(String[] args) {
Parcel2 p = new Parcel2();
p.ship("Tasmania");

Parcel2 q = new Parcel2();
Contents c = q.contents(); //静态方法中调用内部类,应该由外部列对象调用才行
Destination d = q.to("Borneo"); //如:Parcel2.Destination d = q.to("Borneo");
System.out.println(d.readLabel()); //但此类中没有用外部类对象,竟然没有报错,求解释?
}
}


问题描述见注释
环境:jdk1.5
...全文
347 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
bxeldor_coder 2011-06-16
  • 打赏
  • 举报
回复
也不是使用吧。改“转型为”。
bxeldor_coder 2011-06-16
  • 打赏
  • 举报
回复
将调用改为使用吧。
bxeldor_coder 2011-06-16
  • 打赏
  • 举报
回复
LZ是想讨论
Parcel2.Destination

Destination
的区别吧
以下是我的理解:
我觉得他们在编译器眼里是一样的。
即便你在Parcel2外部在定义一个Destination
的类。他也不会调用外部定义的Destination
类。而是直接调用内部类Destination

感觉一般采用第一种写法,是为了让代码有更好的可读性。
qybao 2011-06-16
  • 打赏
  • 举报
回复
这是连着写的,像你原来的代码,可以
Contents c = q.new Contents(); //也就是说需要个外部类实例
hh3755 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 wolfkoala 的回复:]

引用 12 楼 qybao 的回复:

LZ是不是不想通过实例方法返回,想通过new方法得到实例
如果是这样的话,可以先new一个外部实例,再new内部实例

Contents c = newParcel2().new Contents();

诶,还可以这样——厉害
长见识了
[/Quote]
没有什么 ,书后面就会讲了,继续看就是了.
wolfkoala 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 qybao 的回复:]

LZ是不是不想通过实例方法返回,想通过new方法得到实例
如果是这样的话,可以先new一个外部实例,再new内部实例

Contents c = newParcel2().new Contents();
[/Quote]
诶,还可以这样——厉害
长见识了
qybao 2011-06-16
  • 打赏
  • 举报
回复
LZ是不是不想通过实例方法返回,想通过new方法得到实例
如果是这样的话,可以先new一个外部实例,再new内部实例

Contents c = newParcel2().new Contents();
qybao 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 wolfkoala 的回复:]
引用 1 楼 p_rince 的回复:

你现在的主函数已经在类里了
你在写个测试类试试


谢谢你的建议
我刚才试过了,如果在其他类中main,直接调用Parcel2的内部类
报错是:找不到内部类

其实我觉得就算在其他类中,在非静态类中,直接调用Parcel2的内部类,也会报同样的错误(未测试)
因为内部类编译后,class文件名为Parcel2$Contents.cla……
[/Quote]
只要不是static的,就必须通过外部类实例调用,所以其他类也会一样报错的
wolfkoala 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 qybao 的回复:]

我是举个例子,如果是静态调用,就不需要实例,所以我后面紧跟着说,显然是不行的,也就是说必须通过实例调用,那么这个实例就是外部类实例了
[/Quote]

欧,那是我误解了!不好意思,谢谢帮助哈
qybao 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 wolfkoala 的回复:]
所以验证了我上面的结论:“Contents c = contents()”报错原因是:静态方法不能直接调用非静态方法的错误
我觉得如果这样写“Contents c = new Contents()”就应该是静态方法直接调用内部类的错误了
[/Quote]
这两个是一样的错误,都是static不能直接调用static,如果Contents声明为static class就可以调用,同样的,contents声明为static也可以调用(不过这时你的contents方法内的代码就不能直接new内部类了)。


wolfkoala 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 p_rince 的回复:]

你现在的主函数已经在类里了
你在写个测试类试试
[/Quote]

谢谢你的建议
我刚才试过了,如果在其他类中main,直接调用Parcel2的内部类
报错是:找不到内部类

其实我觉得就算在其他类中,在非静态类中,直接调用Parcel2的内部类,也会报同样的错误(未测试)
因为内部类编译后,class文件名为Parcel2$Contents.class和Parcel2$Destination.class

但是通过外部类调用内部类是没问题的
qybao 2011-06-16
  • 打赏
  • 举报
回复
我是举个例子,如果是静态调用,就不需要实例,所以我后面紧跟着说,显然是不行的,也就是说必须通过实例调用,那么这个实例就是外部类实例了
wolfkoala 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 qybao 的回复:]

Parcel2 q = new Parcel2();
Contents c = q.contents(); //静态方法中调用内部类,应该由外部列对象调用才行
contents是Parcel2的实例方法,在该方法内new Contents的,而该方法是通过对象q调用的,所以并不是static方法直接调用内部类,如果是直接调用应该是,Contents c = contents()……
[/Quote]

首先谢谢qybao
确实解决我的问题和疑惑

但是有一个地方我觉的应该是这样的
在你的第一次回复中提到:“如果是直接调用应该是,Contents c = contents()”

我将代码改成Contents c = contents()后
编译报错:无法从静态上下文中引用非静态 方法 contents()
这个应该是静态方法不能直接调用非静态方法的错误

为了验证上面的猜想,在类中添加了writeStr()函数
	public void writeStr() {
System.out.println("no-static && no inner class");
}

在main函数中直接调用该函数
报错:无法从静态上下文中引用非静态 方法 writeStr()

所以验证了我上面的结论:“Contents c = contents()”报错原因是:静态方法不能直接调用非静态方法的错误

我觉得如果这样写“Contents c = new Contents()”就应该是静态方法直接调用内部类的错误了
YI2LI 2011-06-16
  • 打赏
  • 举报
回复
public String getOuterName() {return Parcel2.this.name;} //追加一个查看外部类的方法
qybao 2011-06-16
  • 打赏
  • 举报
回复
这里改一下
public String getOuterName() {return Parcel2.this.name;} //追加一个查看外部类的方法
qybao 2011-06-16
  • 打赏
  • 举报
回复
还是用代码来解释吧
public class Parcel2{
String name; //追加一个外部类属性
public Parcel2(String name) {this.name=name;} //追加一个外部类构造函数
class Contents {
private int i = 11;
public int value() {return i;}
public String getOuterName() {return Parcel2.name;} //追加一个查看外部类的方法
}

class Destination {
private String label;
Destination(String whereTo){
label = whereTo;
}
String readLabel() {return label;}
}

public Destination to(String s){
return new Destination(s);
}

public Contents contents() {
return new Contents();
}

public void ship (String dest){
Contents c = contents();
Destination d = to(dest);
System.out.println(d.readLabel());
}

public static void main(String[] args) {
//Parcel2 p = new Parcel2();
//p.ship("Tasmania");

Parcel2 q = new Parcel2("I am q"); //生成外部类实例
Contents c = q.contents();
System.out.println(c.getOuterName()); //看看c的外部类实例是什么?
Destination d = q.to("Borneo");
System.out.println(d.readLabel());
}
}
qybao 2011-06-16
  • 打赏
  • 举报
回复
Parcel2 q = new Parcel2();
Contents c = q.contents(); //静态方法中调用内部类,应该由外部列对象调用才行
contents是Parcel2的实例方法,在该方法内new Contents的,而该方法是通过对象q调用的,所以并不是static方法直接调用内部类,如果是直接调用应该是,Contents c = contents(); 即不通过对象调用,这显然是不行的,同理to方法也一样,这个外部类实例就是q,因为是通过q调用方法的。Destination d = q.to("Borneo"); //如:Parcel2.Destination d = q.to("Borneo");
System.out.println(d.readLabel()); //但此类中没有用外部类对象,竟然没有报错,求解释?
shawn.bug 2011-06-16
  • 打赏
  • 举报
回复
你现在的主函数已经在类里了
你在写个测试类试试

62,614

社区成员

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

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