局部内部类

局部内部类:定义在外部类成员方法方法体中的类。

  1. 局部内部类只能在方法体内部使用。
  2. 局部内部类可以在方法体内部直接创建对象。
  3. 局部内部类不能用访问控制符和static关键字修饰。
  4. 局部内部类可以使用所在方法体的局部变量,但该局部变量必须用final修饰(这是因为局部内部类使用方法中的局部变量时会将其值拷贝一份放入类中,若局部变量值发生变化,而内部类中仍旧用原来的值计算,则会造成数据的不一致性问题)。

举例:
局部内部类

public class AreaOuter {
    private int num=1;
    public void print(){
        //定义局部变量,必须用final修饰
        final int cnt=2;
        //定义局部内部类
        class AreaInner{
            private int num=3;
            public void print(){
                System.out.println("局部内部类中的num:"+this.num);
                System.out.println("局部变量cnt:"+cnt);
                System.out.println("外部类中的num:"+AreaOuter.this.num);
            }
        }
        AreaInner ai=new AreaInner();
        ai.print();
    }
}

测试类

public class AreaTest {
    public static void main(String[] args) {
        AreaOuter ao=new AreaOuter();
        ao.print();
    }
}

结果如下

Thread类的匿名子类怎么传参数java java匿名类一定是final类吗_匿名内部类

匿名内部类

匿名内部类可以当作一种没有名称的类。当某一个接口或类的实现需要被使用一次时,如果我们新建一个类实现这个接口或者类,就会增加内存的开销。而如果我们使用匿名内部类,则无需创建新的类,达到同样的目的且减少了代码的冗余。

下面通过回调模式举例匿名内部类的作用。

回调模式是指——如果一个方法的参数是接口类型,则在调用该方法时,需要创建并传递一个实现此接口类型的对象;而该方法在运行时会调用到参数对象中所实现的方法(接口中定义的)。

在此先定义一个接口AnonymousInterface

public interface AnonymousInterface {
    public abstract void print();
}

再定义个以接口类型为参数的test方法

public class AnonymousTest {
    public static void test(AnonymousInterface ai){
        ai.print();
    }
    public static void main(String[] args) {
        
    }
}

此时如果希望在mian方法中调用test方法,则需要一个实现了AnonymousInterface接口的类的对象。
(1)若不使用匿名内部类,则需要新建一个实现该接口的类,并将该类对象作为形参传递。如下。

实现该接口的类

public class AnonymousImpl implements AnonymousInterface{
    @Override
    public void print() {
        System.out.println("自定义实现了该接口的类");
    }
}

main方法

public class AnonymousTest {
    public static void test(AnonymousInterface ai){
        ai.print();
    }

    public static void main(String[] args) {
        //新建AnonymousImpl对象作为实参
        AnonymousTest.test(new AnonymousImpl());
    }
}

结果如下

Thread类的匿名子类怎么传参数java java匿名类一定是final类吗_局部变量_02


(2)使用匿名内部类

匿名内部类的语法格式:接口/父类类型 引用变量名 = new 接口/父类类型() { 方法的重写 };

修改main方法如下

public class AnonymousTest {
    public static void test(AnonymousInterface ai){
        ai.print();
    }

    public static void main(String[] args) {
        //使用匿名内部类作为形参
        AnonymousTest.test(new AnonymousInterface(){
            @Override
            public void print() {
                System.out.println("使用匿名内部类");
            }
        });
    }
}

在此匿名内部类可以通俗地表示为新建接口类型的对象并重写方法(当然接口是不能实例化的)。

结果如下

Thread类的匿名子类怎么传参数java java匿名类一定是final类吗_java_03