美文网首页
java 内部类

java 内部类

作者: going_hlf | 来源:发表于2020-11-13 23:58 被阅读0次

一般有四种内部类的使用方式:

  1. 嵌套的内部类
  2. 方法内的内部类
  3. 静态内部类
  4. 匿名内部类

什么时候用内部类:

  1. 有时候明显一个类只有另一个类使用,且他们的关联性较强。(此时使用内部类可以省去为每个类创建文件)
  2. 有些类需要访问另一个类的内部成员,甚至私有成员。如果用两个类实现,需要暴露一些接口出来,为了增强了封装性,可以选择使用内部类。这种情况类似于C++的友元(有人会说,那干脆把内部类和外部类合并算了,但是这样就少了一层抽象,会逐渐形成上帝类)。
  3. 内部类可以的定义在紧邻它使用的地方,从而增强可读性和可维护性。
  4. 当一个内部类只有在某个方法内部使用,且你懒得去为这个内部类想一个名字(通常这个名字没必要,因为外部没人用到它),此时你可以选择匿名内部类(匿名内部类用于实现接口,跟javafx框架结合用起来很方便,待研究)。
  5. A common use of static nested class is ViewHolder design pattern in RecyclerView and ListView(inner class的使用是基于一些设计的需要引入的,待研究)
  6. 内部类是实现类似C++多继承的一种方式(这一条在on java8中被认为是使用内部类最重要的一个理由)。
interface Super{
    void Show();
//    void Method();
}

class Outer {
    // Simple nested inner class
    class Inner1 {
        public void Show() {
            System.out.println("Inner1.Show()");
        }
    }

    void OuterMethod() {
        int para = 5;
        System.out.println("Outer.OuterMethod()");
        // Inner class is local to outerMethod()
        class Inner2 { // [1]
            void Show() {
                System.out.println("Inner2.Show(), inner1.para = " + para);
            }

            @Override
            protected void finalize() {
                System.out.println("\nInner2.finalize(), inner1.para = " + para); // [2]
            }
        }
        Inner2 y = new Inner2();
        y.Show();
        System.out.println("OuterMethod is over!");
    }

    // A static inner class
    static class Inner3 {
        public static void main(String[] args) { // [3] 静态内部类可以有静态main方法
            System.out.println("Inner3.main()");
            new Outer().OuterMethod();
        }

        void Show() {
            System.out.println("Inner3.Show()");
        }
    }

    //  An anonymous class with Demo as base class
    // [4]
    static Super inner4 = new Super() { // 匿名内部类对象可以通过new一个接口,也可以new一个父类来实现。
        @Override
        public void Show() {
            System.out.println("I am in anonymous inner class");
        }
//        @Override
//        public void Method(){}
    };
}

class InnerClassDemo {
    public static void main(String[] args) {
        Outer out = new Outer();

        System.out.println("\ncase 1 out put:");
        Outer.Inner1 in = out.new Inner1(); // 能够这样定义对象的前提是,Inner类不是private属性的。
        in.Show();


        System.out.println("\ncase 2 out put:");
        out.OuterMethod();

        System.out.println("\ncase 3 out put:");
        new Outer.Inner3().Show();

        System.out.println("\ncase 4 out put:");
        out.inner4.Show();

        System.gc(); // [5]

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

输出:

case 1 out put:
Inner1.Show()

case 2 out put:
Outer.OuterMethod()
Inner2.Show(), inner1.para = 5
OuterMethod is over!

case 3 out put:
Inner3.Show()

case 4 out put:
I am in anonymous inner class

Inner2.finalize(), inner1.para = 5

代码中的标注解释:
[1]. 外部类方法OuterMethod中的内部类,不能是private/public/protected/static/transient,但可以是final。因为这个内部类是无法通过OuterMethod之外的任何方法访问的,所以设置权限没有意义。
[2]. JDK 1.8之前,方法内的内部类,不能访问方法内的局部变量,除非变量是final的。(但不知道为什么JDK1.8又能够访问了)。这里使用finalize为了验证可能存在的副作用。
[3]. 不允许非静态内部类中有静态方法。(因为这种情况下,你没有办法调用这个静态方法)
[4]. 匿名内部类内部类用于实现接口,且只有一个方法时,可以使用lambda表达式。可以替换为更简洁的lambda表达式写法: static Super inner4 = () -> System.out.println("i am in anonymous class");
[5]. 在OuterMethod方法调用结束很久后,还访问了其中的局部变量,说明了内部类使用包含它的方法的局部变量可能存在隐患(虽然这里还能打出来值,是因为没有被覆写,但是很危险)。finalize的副作用见gc&finalize()。。

相关文章

  • Java 中的方法内部类

    Java 中的方法内部类 方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内...

  • PHP转JAVA的记录

    Java 数组 内部类 内部类的创建:内部类可以对包内其他类隐藏想实现一个接口时, 不想新建类文件 内部类可以访问...

  • Java内部类

    Java内部类,简单来说就是将一个类定义在另一个类或者方法里面,主要分为成员内部类,局部内部类,匿名内部类和静态内...

  • Java内部类

    Java内部类 大纲: java内部类有什么特点?为什么需要内部类? 非静态内部类持有外部类的引用 内部类的分类。...

  • 内部类

    内部类可以分为:非静态内部类;静态内部类;匿名内部类。 一、内部类 首先要说,Java为什么要使用内部类?java...

  • Java静态内部类

    Java静态内部类 博客分类: java 两种内部类 Java的内部类有两种,一种是静态内部类,另一种是普通内部类...

  • Kotlin内联类、内部类、嵌套类

    Kotlin内联类、内部类、嵌套类 在开始介绍Kotlin内联类、内部类、嵌套类之前,先简要回顾一下java中的内...

  • JavaSE基础知识学习-----内部类

    内部类 类的五个成分:属性,方法,构造器,代码块,内部类。什么是内部类?在java中,允许一个类定义在另一个类的内...

  • Java 内部类和泛型的理解

    Java 内部类 Java非静态内部类持有对外部类的引用,可以访问外部类的状态使用方法 OuterClass.th...

  • kotlin之内部类,匿名内部类与伴生对象

    个人博客:haichenyi.com。感谢关注 内部类   kotlin的内部类与java的内部类有点不同java...

网友评论

      本文标题:java 内部类

      本文链接:https://www.haomeiwen.com/subject/rxhibktx.html