inner java_Java——内部类(InnerClass)

package InnerClass;

public class InnerClassTest { //主类

public static void main(String[] args) {

OuterClass outer = new OuterClass(true);

}

}

package InnerClass;

public class OuterClass { //外部类

private boolean a;

OuterClass(boolean a){

this.a = a;

System.out.println("我是外部类!");

InnerClass inner = new InnerClass();

}

public class InnerClass{ //内部类

InnerClass(){

if(a) {

System.out.println("我是内部类!a:"+a);

}

}

}

}

1. 内部类的特殊语法规则:↓

外部类引用的正确语法:OuterClass.this

例如:

if(OuterClass.this.a) {

System.out.println("我是内部类!a:"+a);

}

反过来,也可以new内部类的构造器

正确语法:outerObject.new InnerClass();

例如:

OuterClass(boolean a){

this.a = a;

System.out.println("我是外部类!");

InnerClass inner = new InnerClass(); //←这里

}

外部类作用域外这样引用内部类:OuterClass.InnerClass

例如:

OuterClass.InnerClass inner = outer.new InnerClass();

2. 内部类是否有用、必要和安全

内部类是一种编译现象,虚拟机无关。编译器将会把内部类翻译成$(美元符号)分隔外部类名与内部类名的常规类文件。

3. 局部内部类

仔细看最上面的代码会发现InnerClass这个类只在OuterClass构造器中引用了一次

这种情况可以在一个构造函数(方法也可以)中定义一个局部类

例如:

OuterClass(boolean a){

this.a = a;

System.out.println("我是外部类!");

InnerClass inner = new InnerClass();

class LocalClass{

LocalClass(){

System.out.println("我是局部内部类");

}

}

LocalClass local = new LocalClass();

}

4. 外部方法访问变量

与其他类相比较,局部类还有一个优点。它不仅能访问包含它们的外部类,还能访问局部变量。不过那些局部变量都必须事实上为Final。这说明它们一旦赋值就不会改变。

这个一个b()方法:

public void b(boolean a) {

class LocalClass{

LocalClass(){

System.out.println("我是局部内部类"+**a**);

}

}

a = true;

LocalClass local = new LocalClass();

}

这个方法看着没什么问题,但是是错误的,局部类在访问a参数时提示了一个错误:

Local variable a defined in an enclosing scope must be final or effectively final

谷歌翻译:在封闭范围中定义的局部变量a必须是最终的或有效的最终

提示说局部变量a要是最终的或有效的最终,也就是变量a(其实a是b()方法的参数)不能改变,这也就说明了局部内部类访问的变量(参数)要设置为final。

正确的代码:

public void b(final boolean a) {

class LocalClass{

LocalClass(){

System.out.println("我是局部内部类"+a);

}

}

// a = true; a参数设置为final就不能有这句代码

LocalClass local = new LocalClass();

}

5. 匿名内部类

假如只创建这个类的一个对象,就不必命名了。这种类被称为匿名内部类(anonymous inner class)。

interface AnonymousInnerClass { //定义一个接口

void anonymous();

}

public void anonymousInnerClass() { //方法

AnonymousInnerClass a = new AnonymousInnerClass() { //方法中的匿名内部类

@Override

public void anonymous() {

System.out.println("匿名内部类");

}

};

a.anonymous();

}

通常格式为:

new SuperType(construction parameters){

inner class methods data

}

Supertype可以是一个接口也可以是一个类,于是内部类就要扩展它

由于构造器名必须与类名一致,而匿名内部类没有类名,所以匿名内部类没有构造函数。

取而代之的是,将构造器参数传递给超类构造器,尤其是在内部了实现接口时候,不能有任何构造参数。

多年来,java程序员习惯的做法是用匿名内部类实现事件监听和其他回调。如今最好还是用Lambdab表达式。

技巧:

双括号初始化,利用内部类语法

假如需要构造一个泛型类数组列表,并且传递到一份方法

ArrayList list = new ArrayList();

list.add("Hello");

list.add("World");

invite(list);

如果不在需要这个数组列表,最好让它作为一个匿名列表。

方法如下:

invite(new ArrayList() {{add("Hello");add("World");}});

6. 静态内部类

有时候,使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外部类对象。为此,可以将内部类声明为static,以便取消产生的引用。

静态内部类-比较两个数的大小:

package InnerClass;

public class StaticInnerClass {

public static void main(String[] args) {

ArrayAlg.minMax(15, 6);

}

}

class ArrayAlg{

public static class Pair{

Pair(int a,int b){

System.out.println("Max:"+(a>b?a:b));

System.out.println("Min:"+(a

}

}

public static Pair minMax(int a,int b){

{

return new ArrayAlg.Pair(a,b);

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值