废话不说 ,上代码。
package innerClass;class Aa{
void m(){
System.out.println("outer");
}
} public class innerClass {
public static void main(String[] args) {
new innerClass().go(); }
void go(){
new Aa().m();
class Aa{
void m(){
System.out.println("inner");
}
}
}
class Aa{
void m(){
System.out.println("middle");
}
}
} 请问 最终结果为什么是 middle 请高手逐行注释解释。
package innerClass;class Aa{
void m(){
System.out.println("outer");
}
} public class innerClass {
public static void main(String[] args) {
new innerClass().go(); }
void go(){
new Aa().m();
class Aa{
void m(){
System.out.println("inner");
}
}
}
class Aa{
void m(){
System.out.println("middle");
}
}
} 请问 最终结果为什么是 middle 请高手逐行注释解释。
首先加载的是InnerClass内
包括它的成员变量,成员方法go()和内部类Aa
在运行到go()中的时候
你new Aa().m() 这个时候 内存中只有InnerClass的内部类Aa
所以打印的是middle
Aa.class,innerClass$1Aa.class,innerClass$Aa.class,innerClass.class
class Aa
{
void m()
{
System.out.println("outer");
}
}
public class innerClass
{
public static void main(String[] args)
{
new innerClass().go();
}
void go()
{
new Aa().m();
class Aa
{
void m()
{
System.out.println("inner");
}
}
}
class Aa
{
void m()
{
System.out.println("middle");
}
}
}
class Aa{
void m(){
System.out.println("Middle");
}
}
void go(){
new Aa().m();//输出Middle class Aa{
void m(){
System.out.println("Inner");
}
}
new Aa().m();//输出Inner
}
public static void main(String[] args) {
new TestInners().go();
}
}
void go(){
System.out.println(i);//输出0;
int i = 1;
System.out.println(i);//输出1;
}
go方法中的内部类的范围是从定义开始,往后。
验证方法:调整go方法中的两条语句的顺序,你会发现是打印inner class;
调整结果: void go(){
class Aa{
void m(){
System.out.println("inner");
}
}
new Aa().m();
}
话说回来,其实你打开java类加载选项的话,会发现
这个类:
class Aa {
void m() {
System.out.println("inner");
}
}
根本都没被加载,说白了就是代码顺序执行和括号作用域的原因。
public class Aa {
void m(){
System.out.println("outer");
}}public class TestInner {
public static void main(String[] args){
new TestInner().go();
}
void go() {
class Aa{
void m(){System.out.println("inner"); }
}
new Aa().m();
}
class Aa{
void m(){
System.out.println("middle");
}
} }个人认为,遵循就近原则,从里往外查找
class中定义变量、方法、内部类都是不分先后顺序的
但方法中定义变量、内部类,调用某个变量或类是必须在调用之前定义楼主的代码 类 "inner" 定义是无效的
首先看第一个例子:public class innerClass
{
public static void main(String[] args)
{
new innerClass().go();
}
void go()
{
new Aa().m();
class Aa
{
void m()
{
System.out.println("inner");
}
}
}如上代码,不能通过编译,因为当编译器执行到new Aa().m();这句话时,由于Aa是方法中的类,暂时还不可见
可是如果改成:public class innerClass
{
public static void main(String[] args)
{
new innerClass().go();
}
void go()
{
class Aa
{
void m()
{
System.out.println("inner");
}
}
new Aa().m();
}便可通过编译,运行结果:inner分析1:
方法内部的类,如果在调用构造器之后才定义该类,该类是不可见的再看第二个例子:public class innerClass
{
public static void main(String[] args)
{
new innerClass().go();
}
void go()
{
new Aa().m();
class Aa
{
void m()
{
System.out.println("inner");
}
}
}
class Aa
{
void m()
{
System.out.println("middle");
}
}
}此时以上代码可以通过编译,运行结果:middle
可是如果把调用构造器的那句话放到方法内部类后面:public class innerClass
{
public static void main(String[] args)
{
new innerClass().go();
}
void go()
{
class Aa
{
void m()
{
System.out.println("inner");
}
}
new Aa().m();
}
class Aa
{
void m()
{
System.out.println("middle");
}
}
}这时也可通过编译,运行结果:inner
进一步做点小改变:public class innerClass
{
public static void main(String[] args)
{
new innerClass().go();
}
void go()
{
new Aa().m();
class Aa
{
void m()
{
System.out.println("inner");
}
}
new Aa().m();
}
class Aa
{
void m()
{
System.out.println("middle");
}
}
}通过编译,运行结果:
middle
inner分析2:
第一段代码,由于方法内部类暂时不可见,所以调用的是方法外部的Aa类的构造器
第二段代码,由于方法内部类在调用构造器之前已经出现了,根据就近原则,调用的是方法内部Aa类的构造器
第三段代码,第一个构造器调用时,方法内部类不可见,因此调用方法外部的Aa类构造器,运行到第二个构造器时,方法内部类Aa已经定义,根据就近原则,调用方法内部类Aa的构造器最后看第三个例子,加入外部Aa类:class Aa
{
void m()
{
System.out.println("outer");
}
}public class innerClass
{
public static void main(String[] args)
{
new innerClass().go();
}
void go()
{
new Aa().m();
class Aa
{
void m()
{
System.out.println("inner");
}
}
new Aa().m();
}
class Aa
{
void m()
{
System.out.println("middle");
}
}
}运行结果还是:
middle
inner分析3:
结果与例二的最后一段代码同,说明有同名内部类时,外部同名的类被完全屏蔽了最后的结论:
1.构造器的调用遵循就近原则,跟构造器最接近的同名类的构造器被调用
2.如果调用构造器的语句,和同名类定义都在方法内部,则该类定义必须出现在调用构造器之前,否则不可见
你最好能从JVM规范上找到依据!或者是某些权威的书上!
否则,不能叫人信服!
非static内部类行为类似方法或属性,但好像没有作用域概念,
成员内部类会屏蔽掉外面那个类.
http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.3Here is an example that illustrates several aspects of the rules given above:class Global {
class Cyclic {}
void foo() {
new Cyclic(); // create a Global.Cyclic
class Cyclic extends Cyclic{}; // circular definition
{
class Local{};
{
class Local{}; // compile-time error
}
class Local{}; // compile-time error
class AnotherLocal {
void bar() {
class Local {}; // ok
}
}
}
class Local{}; // ok, not in scope of prior Local
}The first statement of method foo creates an instance of the member class Global.Cyclic rather than an instance of the local class Cyclic, because the local class declaration is not yet in scope.