匿名内部类详解

原文地址:

 匿名内部类详解    https://www.cnblogs.com/SQP51312/p/6100314.html  (这篇文章写得很好,强烈大家去看原文)

匿名内部类

匿名内部类就是没有名字的内部类;


注意:

匿名内部类不能定义任何静态成员、方法。

匿名内部类中的方法不能是抽象的;

匿名内部类必须实现接口或抽象父类的所有抽象方法。

匿名内部类访问的外部类成员变量或成员方法必须用static修饰;


代码:

接口

public interface Inner {

    public String say();

}

抽象类

public abstract class Inner1 implements Inner{

}

普通类

public class Inner2 implements Inner{

    public String say() {

        return"this is Inner2";

    }

}

外部类

public class Outer {

 

    public static String s1 = "this is s1 in Outer";

    public static String s2 = "this is s2 in Outer";

    private static String s3 = "this is s3 in Outer";

 

    public void method1(Inner inner) {

        System.out.println(inner.say());

    }

 

    private static String method2() {

        return "this is method2 in Outer";

    }

 

    public static void main(String[] args) {

        Outer outer = new Outer();

        // 测试1,Inner为接口

        outer.method1(new Inner() {

            String s1 = "this is s1 inInner";

 

            public String say() {

                // 外部类和匿名函数类中有同名变量s1

                return s1;

            }

        });

        // 测试2,Inner1为抽象类

        outer.method1(new Inner1() {

            String s2 = "this is s2 inInner1";

 

            public String say() {

                // 外部类和匿名函数类中有同名变量s2

                return Outer.s2;

            }

        });

        // 测试3,Inner2为普通类

        outer.method1(new Inner2() {

            public String say() {

                // 访问外部类私有变量s3

                return s3;

            }

        });

        // 测试4,Inner2为普通类

        outer.method1(new Inner2() {

            public String say() {

                // 访问外部类私有方法method1()

                return method2();

            }

        });

    }

}

打印:

this is s1 in Inner

this is s2 in Outer

this is s3 in Outer

this is method2 in Outer

分析:

编译后自动生成四个文件:Outer$1.class、Outer$2.class、Outer$3.class、Outer$4.class。

Outer.class反编译(属性值、方法内容略)

public class jichu.Outer {

  public static java.lang.String s1;

  public static java.lang.String s2;

  private static java.lang.String s3;

  static  {};

  public jichu.Outer();

  public void method1 ( jichu.Inner );

  private static java.lang.String method2();

  public static void main( java.lang.String[] );

  static java.lang.String access$0();

  static java.lang.String access$1();

}

Outer$1.class反编译(经优化、调整)

class Outer$1

  implements Inner

{

  String s1 = "this is s1 in Inner";

 

  public String say()

  {

    return this.s1;

  }

}

Outer$2.class反编译(经优化、调整)

class Outer$2

  extends Inner1

{

  String s2 = "this is s2 in Inner1";

 

  public String say()

  {

    return Outer.s2;

  }

}

Outer$3.class反编译(经优化、调整)

class Outer$3

  extends Inner2

{

  public String say()

  {

    return Outer.access$0();

  }

}

Outer$4.class反编译(经优化、调整)

class Outer$4

  extends Inner2

{

  public String say()

  {

    return Outer.access$1();

  }

}

1、匿名内部类因为没有类名,可知匿名内部类不能定义构造器

2、因为在创建匿名内部类的时候,会立即创建它的实例,可知匿名内部类不能是抽象类,必须实现接口或抽象父类的所有抽象方法

3、匿名内部类会继承一个父类(有且只有一个)或实现一个接口(有且只有一个),实现父类或接口中所有抽象方法,可以改写父类中的方法,添加自定义方法。

5、当匿名内部类和外部类有同名变量(方法)时,默认访问的是匿名内部类的变量(方法),要访问外部类的变量(方法)则需要加上外部类的类名。

6、从Outer.class反编译代码中可看出自动生成了两个静态方法:access$0()和access$1(),并在测试3和测试4中通过Outer类名直接调用,这样实现了内部类对外部类私有成员变量和方法的访问。可知内部类可以访问外部类私有变量和方法


疑问

匿名内部类不能含有static的变量和方法。但是测试发现变量可以被static final修饰,为什么?

主要是因为final类型在编译期间jvm有优化,常量池会维护这些变量。虽然非静态内部类不能脱离外部类这个上下文实例化,但是常量池使得final变量脱离了类实例化这个条件,编译期间便可确定。


总结

1、匿名内部类不能定义任何静态成员、方法。

2、匿名内部类中的方法不能是抽象的;

3、匿名内部类必须实现接口或抽象父类的所有抽象方法。

4、匿名内部类不能定义构造器;

5、匿名内部类访问的外部类成员变量或成员方法必须用static修饰;

6、内部类可以访问外部类私有变量和方法。

 


 






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值