avatar
b*d
1
Runnable r = new Runnable(){
public void run(){
System.out.println(1);
}
}
Thread t = new Thread(r){
public void run(){
System.out.println(2);
}
};
t.start();
结果是2
我的问题是,这里的anonymous inner class怎么还带参数的?这个参数到底怎么理解?
是否相当于
Class Thread1 extends Thread{}
Thread t = new Thread1(r);
那这样启动线程后为什么不执行runnable的run(), 而是执行overriden的Thread里面的
run()?
非常迷惑
avatar
g*g
2
It's easy to figure out from Thread class' source code.
720 public void run() {
721 if (target != null) {
722 target.run();
723 }
724 }
Basically your anonymous inner class override the method above.
And the target (Runnable) no longer applies.

【在 b******d 的大作中提到】
: Runnable r = new Runnable(){
: public void run(){
: System.out.println(1);
: }
: }
: Thread t = new Thread(r){
: public void run(){
: System.out.println(2);
: }
: };

avatar
M*0
3
障眼法,那个参数r看似传进去了,其实没有
你要是在重写的thread里加个constructor:
public Thread(Runnable r)
{
super(r);
}
那就会输出1了
avatar
b*d
4
那为什么不出编译错误?

【在 M***0 的大作中提到】
: 障眼法,那个参数r看似传进去了,其实没有
: 你要是在重写的thread里加个constructor:
: public Thread(Runnable r)
: {
: super(r);
: }
: 那就会输出1了

avatar
M*0
5
确实像是编译错误
你把我说的那个运行看看,我不确定我的答案

【在 b******d 的大作中提到】
: 那为什么不出编译错误?
avatar
b*d
6
好像有点明白了,不过为什么不出编译错误呢?
这个anonymous class没有 thread(Runnable)的constructor的
这样分开写是会报错的
Class Thread1 extends Thread{ public void run(){...}}
Thread t = new Thread1(r);

【在 g*****g 的大作中提到】
: It's easy to figure out from Thread class' source code.
: 720 public void run() {
: 721 if (target != null) {
: 722 target.run();
: 723 }
: 724 }
: Basically your anonymous inner class override the method above.
: And the target (Runnable) no longer applies.

avatar
g*g
7
出什么编译错误?

【在 b******d 的大作中提到】
: 好像有点明白了,不过为什么不出编译错误呢?
: 这个anonymous class没有 thread(Runnable)的constructor的
: 这样分开写是会报错的
: Class Thread1 extends Thread{ public void run(){...}}
: Thread t = new Thread1(r);

avatar
b*d
8
anonymouse class没法定义constructor巴
我只能分开写
Class Thread1 extends Thread{
public Thread1(){
super(r);
}
public void(){
...
}
}
Thread t = new Thread1(r);
这样写,编译通过,不过输出还是2;这里用好虫的解释就说得通了。
不过原来没有constructor的情况下不出编译错误就比较奇怪,难道anonymouse class
是直接继承了constructors???【 在 May20 (South Beach Boy) 的大作中提到: 】
avatar
b*d
9
the constructor Thread1(Runnable) is undefined

【在 g*****g 的大作中提到】
: 出什么编译错误?
avatar
M*0
10
刚google了下,anonymous inner class是没有名字的,所以没法写constructor,但
init block是可以。
这样看来,那个r是无论如何传不进去的,语法上应该是错误的,有可能是java
compiler没有考虑周全
avatar
M*0
11
显然不是啊,直接继承了就输出1了。再说constructor不继承

不过原来没有constructor的情况下不出编译错误就比较奇怪,难道anonymouse class
是直接继承了constructors???

【在 b******d 的大作中提到】
: the constructor Thread1(Runnable) is undefined
avatar
b*d
12
继承的话,编译就能通过;然后执行overriden run(), 不会执行runnable.run()了,看好
虫的回复
一般说constructor不能继承,我不是觉得这个现象很奇怪吗?

class

【在 M***0 的大作中提到】
: 显然不是啊,直接继承了就输出1了。再说constructor不继承
:
: 不过原来没有constructor的情况下不出编译错误就比较奇怪,难道anonymouse class
: 是直接继承了constructors???

avatar
b*d
13
init block也传不了参数阿,怎么也是compilation error才对

【在 M***0 的大作中提到】
: 刚google了下,anonymous inner class是没有名字的,所以没法写constructor,但
: init block是可以。
: 这样看来,那个r是无论如何传不进去的,语法上应该是错误的,有可能是java
: compiler没有考虑周全

avatar
M*0
14
我一直以为这个会输出1
这么设计很费解啊

【在 b******d 的大作中提到】
: anonymouse class没法定义constructor巴
: 我只能分开写
: Class Thread1 extends Thread{
: public Thread1(){
: super(r);
: }
: public void(){
: ...
: }
: }

avatar
b*d
15
这个地方倒可以理解,如果编译通过,就会执行overriden run()
原来之所以执行runnable,是因为thread.run()里面会执行target.run(),现在override
n了,当然就不会执行了。
thread.java是这样的
720 public void run() {
721 if (target != null) {
722 target.run();
723 }
724 }

【在 M***0 的大作中提到】
: 我一直以为这个会输出1
: 这么设计很费解啊

avatar
a*n
16
Yours Run method overrides the Thread.run method. If you call super.run() in
your 'run' method, you will get "1" output.

【在 b******d 的大作中提到】
: Runnable r = new Runnable(){
: public void run(){
: System.out.println(1);
: }
: }
: Thread t = new Thread(r){
: public void run(){
: System.out.println(2);
: }
: };

avatar
M*0
17
那个r没有编译错误,可能是出于语法一致性:anonymous inner class里的方法能不能
被外界调用取决于base class里有没有这个方法,这个好理解,所以constructor被同
理了,compiler syntax checking的时候是根据base class而不是overriden class

【在 b******d 的大作中提到】
: init block也传不了参数阿,怎么也是compilation error才对
avatar
b*d
18
嗯,有道理, 如果调用super.run(), 输出就是1了,确实是执行thread(Runnable),赋
值成功了。
不过constructor也参考reference type很别扭阿,比如我分开写就不行,看来是一个
很tricky的地方。

【在 M***0 的大作中提到】
: 那个r没有编译错误,可能是出于语法一致性:anonymous inner class里的方法能不能
: 被外界调用取决于base class里有没有这个方法,这个好理解,所以constructor被同
: 理了,compiler syntax checking的时候是根据base class而不是overriden class

avatar
f*n
19
如果anonymous class不明白就可以不用anonymous class咯。上面的和这个有名的
class一样:
class Foo extends Thread{
public Foo(Runnable r) {
super(r);
}
public void run(){
System.out.println(2);
}
};
Thread t = new Foo(r);
t.start();
现在看得懂了吗?
avatar
b*d
20
anonymouse constructor的官方定义在这里,真是天书阿
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jl

【在 M***0 的大作中提到】
: 那个r没有编译错误,可能是出于语法一致性:anonymous inner class里的方法能不能
: 被外界调用取决于base class里有没有这个方法,这个好理解,所以constructor被同
: 理了,compiler syntax checking的时候是根据base class而不是overriden class

avatar
b*d
21
看懂了,不过
public Foo(Runnable r) {
super(r);
}
是编译器自己加进去的吗? 还是根据reference type引用super(Runnable)的?

【在 f*******n 的大作中提到】
: 如果anonymous class不明白就可以不用anonymous class咯。上面的和这个有名的
: class一样:
: class Foo extends Thread{
: public Foo(Runnable r) {
: super(r);
: }
: public void run(){
: System.out.println(2);
: }
: };

avatar
b*d
22
看官方天书的意思,好像是constructor被继承了。。。
An anonymous class cannot have an explicitly declared constructor. Instead,
a Java compiler must automatically provide an anonymous constructor for the
anonymous class. The form of the anonymous constructor of an anonymous class
C with direct superclass S is as follows:
If S is not an inner class, or if S is a local class that occurs in a st
atic context, then the anonymous constructor has one formal parameter for ea
ch actual argument to the class instance creation expression in which C is d
eclared.
The actual arguments to the class instance creation expression are used
to determine a constructor cs of S, using the same rules as for method invoc
ations (§15.12).
The type of each formal parameter of the anonymous constructor must be i
dentical to the corresponding formal parameter of cs.
The body of the constructor consists of an explicit constructor invocati
on (§8.8.7.1) of the form super(...), where the actual arguments are the fo
rmal parameters of the constructor, in the order they were declared.

不能
被同
class

【在 b******d 的大作中提到】
: anonymouse constructor的官方定义在这里,真是天书阿
: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jl

avatar
M*0
23
刚才没电脑,现在试了一下,还真是继承了
class A
{
int x;
A()
{
x=1;
}
A(int x)
{
this.x = x;
}
int getX()
{
return 0;
}
}
public class OTest
{
public static void main(String[] args)
{
A a = new A(2)
{
int getX()
{
return x;
}
};
System.out.println(a.getX());
}
}
输出2

,
the
class
st
ea
d
used

【在 b******d 的大作中提到】
: 看官方天书的意思,好像是constructor被继承了。。。
: An anonymous class cannot have an explicitly declared constructor. Instead,
: a Java compiler must automatically provide an anonymous constructor for the
: anonymous class. The form of the anonymous constructor of an anonymous class
: C with direct superclass S is as follows:
: If S is not an inner class, or if S is a local class that occurs in a st
: atic context, then the anonymous constructor has one formal parameter for ea
: ch actual argument to the class instance creation expression in which C is d
: eclared.
: The actual arguments to the class instance creation expression are used

avatar
a*n
24
java cert 的考题呀

刚才没电脑,现在试了一下,还真是继承了
class A
{
int x;
A()
……

【在 M***0 的大作中提到】
: 刚才没电脑,现在试了一下,还真是继承了
: class A
: {
: int x;
: A()
: {
: x=1;
: }
: A(int x)
: {

avatar
M*0
25
应该不是。我上半年考的,书和考试都没有关于anonymous inner class的constructor
,这个多半不在objectives里

【在 a******n 的大作中提到】
: java cert 的考题呀
:
: 刚才没电脑,现在试了一下,还真是继承了
: class A
: {
: int x;
: A()
: ……

avatar
f*n
26
I don't understand what's so hard about this.
An anonymous class is anonymous -- it doesn't have a name. It doesn't need
explicit constructors, because there is only one way it can be created.
Anything that can be accomplished with an explicit constructor, can be
accomplished with the implicit constructor that calls the superclass
constructor, initializer block, and capturing of variables.
When you have an anonymous class creation expression like this:
A x = new A(args) {
// members
};
It is basically translated into this (not literally, but the same effect):
class SecretName extends A {
SecretName(args) { super(args); }
// members
};
A x = new SecretName(args);

Wrong. It is perfectly valid.
Wrong. It is perfectly valid.
In Java, what methods you can call on a reference depends on the type of the
reference. Always. Since anonymous class is anonymous, there is no type
name for it, and no variable will be of that type. So of course the variable
must be some superclass of it. It might be Thread, Runnable, or Object. If
it's Thread, then you can call Thread methods on it. If the variable is type
Object, then you can only call Object methods on it. There is nothing
special about anonymous classes.

【在 M***0 的大作中提到】
: 确实像是编译错误
: 你把我说的那个运行看看,我不确定我的答案

avatar
b*d
27
its not hard to understand now after learning constructor can be inherited
but logic is different from grammar.
right logic(understandable in this case) is not always right grammar.
Constructor inheritence is rarely mentioned or used, plus it is explicitly n
oticed that its not inheritable in all the books.
so constructor inheritance in anonymouse class is indeed a very weird design
, and inconsistent with the design in other part of java language.【 在
fakeshawn (spoon!) 的大作中提到: 】
avatar
b*d
28
its in one of the mock test, which is supposed to be a former "real"
question

constructor

【在 M***0 的大作中提到】
: 应该不是。我上半年考的,书和考试都没有关于anonymous inner class的constructor
: ,这个多半不在objectives里

avatar
b*d
29

不能
被同
class
the
variable
If
type
There is no other places constructor can be called based on the reference
type, so it is very special in the anonymous classes, without mentioning
that constructors can not be inherited in all other classes.
like the explanation you gave above, automatically adding content to the
class by the compliler is a very unique situation.

【在 f*******n 的大作中提到】
: I don't understand what's so hard about this.
: An anonymous class is anonymous -- it doesn't have a name. It doesn't need
: explicit constructors, because there is only one way it can be created.
: Anything that can be accomplished with an explicit constructor, can be
: accomplished with the implicit constructor that calls the superclass
: constructor, initializer block, and capturing of variables.
: When you have an anonymous class creation expression like this:
: A x = new A(args) {
: // members
: };

avatar
b*d
30
by the way, reference type doesn't always decide which method should be
called. if its an instance overriden method, the object type decide which
method to be called, so it is more complicated than you think.
Reference does NOT ALWAYS decide which method to be called, and whether
constructor call should follow routine of instance method or class method is
not so intuitive to figure out.

【在 f*******n 的大作中提到】
: I don't understand what's so hard about this.
: An anonymous class is anonymous -- it doesn't have a name. It doesn't need
: explicit constructors, because there is only one way it can be created.
: Anything that can be accomplished with an explicit constructor, can be
: accomplished with the implicit constructor that calls the superclass
: constructor, initializer block, and capturing of variables.
: When you have an anonymous class creation expression like this:
: A x = new A(args) {
: // members
: };

avatar
M*0
31
这个还是很special的。所有书都提醒你constructor不继承,有关inner class的章节
也没指出这个例外情况

There is nothing special about anonymous classes.
我刚才有试了一下,这个其实不能叫constructor inheritance:
class A
{
A()
{
System.out.println("constructor");
}
A(int x)
{
System.out.println("constructor int");
}
int getX()
{
return 0;
}
}
public class OTest
{
public static void main(String[] args)
{
A a = new A(2)
{
public int getX()
{
return 0;
}
};
a.getX();
}
}
只输出一行constructor int
如果是继承了,应该看到两行输出:
constructor (父类的constructor)
constructor int (子类的constructor)
严格上说是default constructor is added
design
那些mock exam不是真题吧,实际考试比mock exam不是简单得一点点

【在 f*******n 的大作中提到】
: I don't understand what's so hard about this.
: An anonymous class is anonymous -- it doesn't have a name. It doesn't need
: explicit constructors, because there is only one way it can be created.
: Anything that can be accomplished with an explicit constructor, can be
: accomplished with the implicit constructor that calls the superclass
: constructor, initializer block, and capturing of variables.
: When you have an anonymous class creation expression like this:
: A x = new A(args) {
: // members
: };

avatar
f*n
32
No, I didn't say it decides *which* method is called. I said it decides *
what* methods *can be* called.

is

【在 b******d 的大作中提到】
: by the way, reference type doesn't always decide which method should be
: called. if its an instance overriden method, the object type decide which
: method to be called, so it is more complicated than you think.
: Reference does NOT ALWAYS decide which method to be called, and whether
: constructor call should follow routine of instance method or class method is
: not so intuitive to figure out.

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。