[#0x0012] 内部类:对外部类的访问及.this和.new

  先上代码: 

class Outer 
{ 
	public class Inner 
	{ 
		public String getInnerClassName() 
		{ 
			return Inner.this.getClass().toString(); //'Inner' can be omitted here 
		}
		
		public String getOuterClassName() 
		{ 
			return Outer.this.getClass().toString(); //'Outer' CANNOT be omitted here 
		} 
	} 
	
	public Inner createInner() 
	{ 
		return new Inner(); //'return this.new Inner();' is OK here 
	} 
} 

public class InnerTest 
{ 
	public static void main(String[] args) 
	{ 
		Outer o = new Outer(); 
		Outer.Inner i1 = o.new Inner(); 
		Outer.Inner i2 = o.createInner(); 
		
		System.out.println(i1.getOuterClassName()); 
		System.out.println(i2.getInnerClassName()); 
	} 
} 

//output: 
/* 
	class Outer
	class Outer$Inner 
*/

 

1. .new

 

  内部类对象是不能直接创建的。必须先创建一个外部类对象,再由这个外部类对象来创建内部类对象。这样处理可能是为了体现内部类对象是依存外部类对象存在的,即内部类对象不能脱离外部类对象而存在。一个外部类对象可以创建多个内部类对象(类似Process与Thread的关系)。创建方法有2种:

  • OuterClassObj.new InnerClass():即使用.new和内部类构造器,如上面代码中的:
Outer.Inner i1 = o.new Inner();

  

  • OuterClassObj.InnerClassConstructorProxy():即使用在外部类中定义的内部类构造器的代理方法,如上面代码中的:
Outer.Inner i2 = o.createInner();

 

  上面2种方法其实是等价的。

 

  这里注意,内部类的声明类型必须是Outer.Inner,编译出的文件为Outer$Inner.class。

 

2. .this  

 

  其实可以把this当作class的一个static field,就算不用内部类,也可以照样用class.this形式,如上面代码中的:

public String getInnerClassName() 
{ 
	return Inner.this.getClass().toString(); //'Inner' can be omitted here 
}

 

  不过鉴于内部类和外部类的特殊关系,内部类必须能够访问其创建者,所以在内部类中可以使用Outer.this来指向创建这个内部类对象的外部类对象。如: [code="java"][/code]

public String getOuterClassName() 
{ 
	return Outer.this.getClass().toString(); //'Outer' CANNOT be omitted here 
}

 

p.s. 总结一点,.this与class连用(类似staitc,class.this),.new与reference连用(obj.new)。

 

3. 对外部类的field和function的访问  

 

  就如同我们在一般类的方法或是constructor中省略this一样,内部类的方法也是如此,只是内部类中省略的是this(i.e. Inner.this)和Outer.this这2个this。所以看上去在内部类的方法中可以直接访问外部类的field/function,而且无论是哪种访问权限的field/function都可以访问,其实是因为内部类方法中可以通过Outer.this链接到外部类,由外部类来访问外部类的field/function,自然是可以不考虑访问权限了。   

  如果内部类和外部类有同名的field/function,单纯使用SameFieldName或是SameFunctionName()会被优先识别为内部类的field/function,如果想要用外部类的field/function,必须用Outer.this来指定。   

  如果你手中只有内部类对象,比如i1、i2,这样是无法直接访问外部类的field/function的,因为外部类的field/function并不属于内部类,类似i1.OuterField或是i2.OuterFunction()是无法通过编译的。所以i1、i2想要访问外部类的field/function只能间接通过内部类的方法。   

  总之,简单的说,内部类对象要想访问外部类对象的field或是function的话,必须要先获得创建自己的外部类对象的引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值