新建对象的疑问
对于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()给覆盖了。
现象比较好玩,但是不知道这是什么语法,还请有识者指点一下。
////////////////////////////////////分隔线(2015年10月27日)////////////////////////////////////////////////////
今天无意在 Oracle官方网站上学习 Nested Class 相关语法时,找到了解答:
http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
■ Syntax of Anonymous Classes As mentioned previously, an anonymous class is an expression. The syntax of an anonymous class expression is like the invocation of a constructor, except that there is a class definition contained in a block of code. The anonymous class expression consists of the following: ● the new operator ● The name of an interface to implement or a class to extend. In this example, the anonymous class is implementing the interface HelloWorld. ● Parentheses that contain the arguments to a constructor, just like a normal class instance creation expression. Note: When you implement an interface, there is no constructor, so you use an empty pair of parentheses, as in this example. ● A body, which is a class declaration body. More specifically, in the body, method declarations are allowed but statements are not. ■ Accessing Local Variables of the Enclosing Scope, and Declaring and Accessing Members of the Anonymous Class Like local classes, anonymous classes can capture variables; they have the same access to local variables of the enclosing scope: ● An anonymous class has access to the members of its enclosing class. ● An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final. ● Like a nested class, a declaration of a type (such as a variable) in an anonymous class shadows any other declarations in the enclosing scope that have the same name. See Shadowing for more information. Anonymous classes also have the same restrictions as local classes with respect to their members: ● You cannot declare static initializers or member interfaces in an anonymous class. ● An anonymous class can have static members provided that they are constant variables. Note that you can declare the following in anonymous classes: ● Fields ● Extra methods (even if they do not implement any methods of the supertype) ● Instance initializers ● Local classes However, you cannot declare constructors in an anonymous class.
从上面的解释来看:
其实,我上面的写法,就相当于声明了一个匿名类,这个匿名类是 Person 类的一个子类(但是没有显示进行定义)。另外,虽然在这个 匿名类 中增加了一个 bbb() 方法,但是因为 Person 类中并没有 bbb()这个方法,而且 p 变量又是 Person 类的一个实例,所以无法通过 p 变量去调用 bbb() 方法。
上一篇: 旅游企业使用大数据必将成为最终赢家