Java新建对象 语法 的疑问


对于Java中新建一个对象,大家可能再熟悉不过了,如:

   
  public class Person {
  

private String name;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public String aaa() {
return "AAA";
}

public static void main(String[] args) {
Person p = new Person();
p.setName("123");
System.out.println(p.getName());
}
}

上面的main方法中的 新建对象方式,对于每个Javaer来说,都不应该有任何疑问。
但是,今天在看Struts2源码时,遇到了以下的代码:

   
  protected List<String> extensions = new ArrayList<String>() {{
  
add("action");
add("");
}};

一开始还楞了一下,怀疑这代码能运行么?
因为这跟我以前声明list的方式不一样,相比之前,我们一般都是如下来声明并初始化list的:

   
  protected List<String> extensions = new ArrayList<String>();
  
extensions.add("action");
extensions.add("");

然后我就脑洞开了一下,既然List可以这么来写,那么其他类是不是也可以这么搞呢?
就拿本文开头的Person类来举例吧,我发现如下这样声明也是可以的:

   
  public class Person {
  

private String name;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public String aaa() {
return "AAA";
}

public static void main(String[] args) {
Person p = new Person() {
{
setName("123");

}

public String aaa() {
return "aaa";
}

public String bbb() {
return "bbb";
}
};

System.out.println(p.name);
System.out.println(p.aaa());
}
}

这样看起来感觉 很怪,但是它是可以运行的,而且它的运行结果是:

   
  123
  
aaa

也就是 Person类中定义的aaa()方法被 p 实例中的aaa()给覆盖了。

现象比较好玩,但是不知道这是什么语法,还请有识者指点一下。

java

英俊小猛男 9 years, 5 months ago

Person p = new Person(){....};
实际上相当于
class PersonChild extends Person{
......
}
Person p = new PersonChild ();

至于为什么打印123,是因为构造块的原因
aaa 是因为你覆写了aaa()这个方法

天使D丨光丨 answered 9 years, 5 months ago

这个问题涉及到了两个基本语法.
1. new A (){XXXX} 这个语法中,xxxx是对A原有方法的覆写.评论中Thread的例子,即可证明 这个我相信楼主是没有争议的.
2. new A () {{XXXXXX}}, 那么大括号中又嵌的{XXXXX}是什么呢, 答: 是java语法中的构造块. java语法中,构造类时需要调用构造函数,如果有构造块,还需要调用构造块(相当于构造函数的补充). 如果不太明白,去百度一下java的构造块和静态块的知识.
3. 所以new A () {{XXXXXX}}语法,就是覆写了A的构造块. 那么new 的时候,肯定就会执行改块代码了. 另外这个写法不怎么好, 除非你明确知道A里面没有构造块, 你才这么做.否则你可能破坏了原有逻辑.

geney answered 9 years, 5 months ago

Your Answer