search.png
关于我
menu.png
Java review(14) 各式内部类总结
  1. 静态内部类:
    • 静态内部类可以声明任意类型的成员和方法,和外部类无异
    • 静态内部类无法使用外部的非静态成员、非静态方法
    • 但是可以任意使用外部的静态成员和静态方法
  2. 非静态内部类
    • 非静态内部类不能声明静态成员和静态方法
    • 非静态内部类可以声明非静态成员和非静态方法
    • 非静态内部类可以声明 常量
    • 非静态内部类可以任意使用外部的成员和方法,静态和非静态的都可以
  3. 方法内部类
    • 方法内部类不能声明为静态的
    • 方法内部类不能声明静态成员和静态方法
    • 方法内部类可以声明非静态成员和非静态方法
    • 方法内部类可以声明 常量
    • 方法内部类可以使用其外部方法的变量,但是不能修改它,也就是隐性的final
    • 非静态方法内部类可以任意使用外部的成员和方法,静态和非静态的都可以
    • 静态方法内部类无法使用外部的非静态成员、非静态方法,但是可以任意使用外部的静态成员和静态方法
  4. 匿名内部类
    • 内部类不能声明静态成员和静态方法
    • 内部类可以声明非静态成员和非静态方法
    • 内部类可以声明 常量
    • 非静态匿名内部类可以任意使用外部的成员和方法,静态和非静态的都可以
    • 静态匿名内部类无法使用外部的非静态成员、非静态方法,但是可以任意使用外部的静态成员和静态方法
  5. lambda (lambda可以算是匿名内部类的语法糖)
    • 受限于lambda的语法,无法在其内部声明成员变量。其内部声明变量的规则和方法无异
    • 非静态lambda 表达式可以任意使用外部的成员和方法,静态和非静态的都可以
    • 静态lambda 表达式无法使用外部的非静态成员、非静态方法,但是可以任意使用外部的静态成员和静态方法
    • 方法内部的lambda表达式可以使用其外部方法的变量,但是无法修改它,也就是隐性的final
    • 非静态方法内部的lambda表达式可以任意使用外部的成员和方法,静态和非静态的都可以
    • 静态方法内部的lambda 表达式无法使用外部的非静态成员、非静态方法,但是可以任意使用外部的静态成员和静态方法

我是怎么得出结论的呢,看代码吧:

package cn.hengyumo.review.r2;

import org.junit.Test;

/**
 * Test3
 * static 关键字
 *
 * @author hengyumo
 * @version 1.0
 * @since 2019/11/29
 */
public class Test3 {

    String noStaticVal = "no static val";
    static String staticVal = "static val";

    void noStaticMethod() {
        System.out.println("no static method");
    }
    static void staticMethod() {
        System.out.println("static method");
    }

    static class A {
        // 静态内部类可以声明任意类型的成员和方法,和外部类无异
        static String sa = "";
        static void sa() {}
        String a = "";
        void a() {}
        final static String A = "";

        void test() {
            // 静态内部类无法使用外部的非静态成员、非静态方法

            // 报错: Non-static field 'noStaticVal' cannot be referenced from a static context
            // System.out.println(noStaticVal);


            // 报错:Non-static method 'noStaticMethod()' cannot be referenced from a static context
            // noStaticMethod();


            // 但是可以任意使用外部的静态成员和静态方法
            System.out.println(staticVal);
            staticMethod();
        }
    }

    class B {
        // 非静态内部类不能声明静态成员和静态方法
        // static String sa = "";
        // static void sa() {}

        // 非静态内部类可以声明非静态成员和非静态方法
        String a = "";
        void a() {}

        // 非静态内部类可以声明 常量
        final static String A = "";

        void test() {
            // 非静态内部类可以任意使用外部的成员和方法,静态和非静态的都可以
            System.out.println(noStaticVal);
            noStaticMethod();
            System.out.println(staticVal);
            staticMethod();
        }
    }

    void methodClass() {
        // 方法内部类不能声明为静态的
        // static class C {
        //
        // }

        String methodVal = "method val";

        final String finalMethodVal = "final method val";

        class C {

            // 方法内部类不能声明静态成员和静态方法
            // static String sa = "";
            // static void sa() {}

            // 方法内部类可以声明非静态成员和非静态方法
            String a = "";
            void a() {}

            // 方法内部类可以声明 常量
            final static String A = "";

            void test() {
                // 方法内部类可以任意使用外部的成员和方法,静态和非静态的都可以
                System.out.println(noStaticVal);
                noStaticMethod();
                System.out.println(staticVal);
                staticMethod();

                // 方法内部类可以使用其外部方法的变量
                System.out.println(methodVal);
                System.out.println(finalMethodVal);

                // 但是不能改变外部方法的变量
                // methodVal = "";
            }
        }
        C c = new C();
        c.test();
    }

    static void staticMethodClass() {
        // 静态方法内部类不能声明为静态的
        // static class D {
        //
        // }

        String methodVal = "method val";

        final String finalMethodVal = "final method val";

        class D {

            // 静态方法内部类不能声明静态成员和静态方法
            // static String sa = "";
            // static void sa() {}

            // 方法内部类可以声明非静态成员和非静态方法
            String a = "";
            void a() {}

            // 方法内部类可以声明 常量
            final static String A = "";

            void test() {
                // 静态方法内部类无法使用外部的非静态成员、非静态方法
                // System.out.println(noStaticVal);
                // noStaticMethod();

                // 静态方法内部类可以使用用外部的静态成员、静态方法
                System.out.println(staticVal);
                staticMethod();

                // 方法内部类可以使用其外部方法的变量
                System.out.println(methodVal);
                System.out.println(finalMethodVal);

                // 但是不能改变外部方法的变量
                // methodVal = "";
            }
        }
        D d = new D();
        d.test();
    }

    interface E {
        void test();
    }
    // 匿名内部类
    E e = new E() {
        // 匿名内部类不能声明静态成员和静态方法
        // static String sa = "";
        // static void sa() {}

        // 匿名内部类可以声明非静态成员和非静态方法
        String a = "";
        void a() {}

        // 匿名内部类可以声明 常量
        final static String A = "";

        @Override
        public void test() {
            // 匿名内部类可以任意使用外部的成员和方法,静态和非静态的都可以
            System.out.println(noStaticVal);
            noStaticMethod();
            System.out.println(staticVal);
            staticMethod();
        }
    };

    // 静态匿名内部类
    static E e2 = new E() {
        // 静态匿名内部类不能声明静态成员和静态方法
        // static String sa = "";
        // static void sa() {}

        // 静态匿名内部类可以声明非静态成员和非静态方法
        String a = "";
        void a() {}

        // 静态匿名内部类可以声明 常量
        final static String A = "";

        @Override
        public void test() {
            // 静态匿名内部类无法使用外部的非静态成员、非静态方法
            // System.out.println(noStaticVal);
            // noStaticMethod();

            // 但是可以任意使用外部的静态成员和静态方法
            System.out.println(staticVal);
            staticMethod();
        }
    };

    // lambda
    E e3 = () -> {
        // lambda 表达式可以任意使用外部的成员和方法,静态和非静态的都可以
        System.out.println(noStaticVal);
        noStaticMethod();
        System.out.println(staticVal);
        staticMethod();
        // 并且可以改变它
        noStaticVal = "no static val";
        staticVal = "static val";
    };

    // 静态lambda
    static E e4 = () -> {
        // 静态lambda 表达式无法使用外部的非静态成员、非静态方法
        // System.out.println(noStaticVal);
        // noStaticMethod();

        // 但是可以任意使用外部的静态成员和静态方法
        System.out.println(staticVal);
        staticMethod();
        // 并且可以改变它
        // noStaticVal = "no static val";
        staticVal = "static val";
    };

    void noStaticLambdaMethod() {
        String methodVal = "method val";

        final String finalMethodVal = "final method val";

        E e3 = () -> {
            // lambda 表达式可以任意使用外部的成员和方法,静态和非静态的都可以
            System.out.println(noStaticVal);
            noStaticMethod();
            // 并且可以改变它
            System.out.println(staticVal);
            staticMethod();
            noStaticVal = "no static val";
            staticVal = "static val";

            // 只能使用方法外部的变量,但是不能改变它
            System.out.println(methodVal);
            System.out.println(finalMethodVal);
            // methodVal = "";
            // finalMethodVal = "";
        };
        e3.test();
    }

    static void staticLambdaMethod() {
        String methodVal = "method val";

        final String finalMethodVal = "final method val";

        E e3 = () -> {
            // 静态方法内的lambda 无法使用外部的非静态成员和成员方法
            // System.out.println(noStaticVal);
            // noStaticMethod();
            // 但似乎可以使用静态的成员和成员方法
            System.out.println(staticVal);
            staticMethod();
            // noStaticVal = "no static val";
            staticVal = "static val";

            // 只能使用方法外部的变量,但是不能改变它
            System.out.println(methodVal);
            System.out.println(finalMethodVal);
            // methodVal = "";
            // finalMethodVal = "";
        };
        e3.test();
    }

    @Test
    public void test1() throws Exception {
        Test3 t = new Test3();
        System.out.println("----------静态内部类-----------");
        // 声明静态内部类:
        Test3.A a = new Test3.A();
        a.test();

        System.out.println("----------非静态内部类-----------");
        // 声明非静态内部类
        B b = t.new B();
        b.test();

        System.out.println("----------非静态的方法的内部类-----------");
        t.methodClass();

        System.out.println("----------静态的方法的内部类-----------");
        Test3.staticMethodClass();

        System.out.println("----------非静态匿名内部类-----------");
        e.test();

        System.out.println("----------静态匿名内部类-----------");
        e2.test();

        System.out.println("----------非静态lambda-----------");
        e3.test();

        System.out.println("----------静态lambda-----------");
        e4.test();


        System.out.println("----------非静态方法内的lambda-----------");
        t.noStaticLambdaMethod();

        System.out.println("----------静态方法内的lambda-----------");
        Test3.staticLambdaMethod();
    }
}

输出:

----------静态内部类-----------
static val
static method
----------非静态内部类-----------
no static val
no static method
static val
static method
----------非静态的方法的内部类-----------
no static val
no static method
static val
static method
method val
final method val
----------静态的方法的内部类-----------
static val
static method
method val
final method val
----------非静态匿名内部类-----------
no static val
no static method
static val
static method
----------静态匿名内部类-----------
static val
static method
----------非静态lambda-----------
no static val
no static method
static val
static method
----------静态lambda-----------
static val
static method
----------非静态方法内的lambda-----------
no static val
no static method
static val
static method
method val
final method val
----------静态方法内的lambda-----------
static val
static method
method val
final method val

版权声明

知识共享许可协议 本文章由作者“衡于墨”创作,转载请注明出处,未经允许禁止用于商业用途

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
发布时间:2019年11月29日 13:12:27

评论区#

还没有评论哦,期待您的评论!

关闭特效