美文网首页
Java内部类

Java内部类

作者: Arvesynden | 来源:发表于2019-09-28 22:40 被阅读0次

一、外部类

只能用public、default修饰的类,外部顶级类的类名需和文件名相同,且一个文件中只能有一个public类。

如存在文件A.java

public class A{//顶级外部类

       //methods。。。

}

public class B{}//编译报错

class C{}//外部类



二、内部类

      内部类,即嵌套类(Nested Classes)。嵌套类包括静态内部类(Static Nested Classes)和内部类(Inner Classes)。而内部类分为成员内部类,局部内部类(Local Classes)和匿名内部类(Anonymous Classes)。

       内部类是一个编译是的概念,一旦编译成功,就会成为完全不同的两个类,分别为Outer.class和Outer$Inner.class类。所以内部类的成员变量/方法名可以和外部类的相同。

       内部类实现多重继承 (让多个内部类分别继承多个其他类,使外部类可以同时获取多个其他类的属性)。

1、静态内部类

    static 修饰的内部类。

    1)静态内部类可以使用public、protected、private、static修饰符修饰

    2)静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问

    3)如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员

    4)创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名 = new 内部类();

public class Outer{

         private int age = 1;            

         static String name = "A";            

         public static class Inner{                

                 String name = "B";//外部类的静态成员与内部类的成员名称可以相同               

                  public void show(){                    

                         System.out.println(Outer.name);  //通过“类名.静态成员”访问外部类的静态成员                 

                         System.out.println(name);                                   

                  }            

          }            

          public static void main(String[] args){                

                 Inner i = new Inner(); //创建静态内部类的对象时,不需要外部类的对象              

                 i.show();            

           }

}

2、非静态内部类

    非静态内部类能访问外部类的一切成员, 包括私有成员。外部类虽然不能直接访问内部类的成员, 但是可以通过内部类的实例访问内部类的私有成员。

(1)成员内部类

       定义在外部类里的非static类。

       1)成员内部类可以使用可以使用任意访问控制符 ,如public 、 protected 、 private 等

       2)成员内部类可以直接使用外部类的所有成员和方法,即使是private修饰的。而外部类要访问内部类的所有成员变量和方法,则需要通过内部类的对象来获取。(可理解为你父母(外部类)的所有东西你(内部类)可以随意使用,而父母想要使用你的东西必须经过你的同意。)

        3)成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建它自己的。

        4)成员内部类可以有常量

        原因:①在加载静态域时,根本没有外部类,所在在非静态内部类中不能定义静态域或方法,编译不通过;非静态内部类的作用域是实例级别②常量是在编译期就确定的,放在常量池

public class Outer {

      private int age = 1;

      String name = "A";

      public class Inner {

            String name = "B";

            public void show() {

                  System.out.println(Outer.this.name);//访问外部类的同名成员要使用this关键字

                  System.out.println(name);

                  System.out.println(age);//成员内部类可以直接使用外部类的私有成员和方法

            }

      }

      public Inner getInnerClass() {

           return new Inner();

      }

      public static void main(String[] args) {

            Outer o = new Outer();

            Inner in = o.new Inner();//必须使用外部类对象来创建成员内部类对象

            in.show();

      }

}


(2)局部内部类

        定义在方法中的内部类,只能在该方法的作用域中使用,与局部变量类似。

       1)和局部变量一样,不能有 public、protected、private 以及 static 修饰符

       2)在jdk1.8之前,只能访问方法中定义的 final 类型的局部变量

               原因:当方法被调用运行完毕之后,局部变量失效。但内部类对象可能还存在,直到没有被引用时才会失效。此时内部类要访问一个不存在的局部变量,是不允许的;对于final变量,Java中采用copy local variable的实现,将final变量拷贝一份存在局部内部类中,后续使用持续维护这个对象在生命周期内。

public class Outer{

    public void Show(){

        final int a = 25;

        int b = 13;

        class Inner{

            int c = 2;

            public void print(){

                System.out.println("访问外部类:" + a);//局部内部类可以访问方法中的final变量

                System.out.println("访问内部类:" + c);

            }

        }

        Inner i = new Inner();

        i.print();

    }

    public static void main(String[] args){

        Outer o = new Outer();

        o.Show();

    }

}

注意:在JDK8版本之中,方法内部类中调用方法中的局部变量,可以不需要修饰为 final,匿名内部类也是一样的,主要是JDK8之后增加了 Effectively final 功能 反编译jdk8编译之后的class文件,发现内部类引用外部的局部变量都是 final 修饰的 (在网上看到别的牛人分析的)

(3)匿名内部类

    是直接使用 new 来生成一个对象的引用,常用于GUI事件处理。

    1)仅能被使用一次,创建匿名内部类时它会立即创建一个该类的实例,不能够被重复使用;

     2)匿名内部类必须是继承一个类或实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口,必须要实现继承的类或者实现的接口的所有抽象方法

     3)匿名内部类中不能定义构造函数,不能存在任何的静态成员变量和静态方法

     4)使用构造代码块初始化匿名内部类

public class Outer {

       public Inner getInner(int num) {//匿名内部类构造代码块

              return new Inner() {//匿名内部类

                     int number = num + 3;

                      public int getNumber() {

                             return number;

                      }

               }; /* 注意:分号不能省略 */

       }

       public static void main(String[] args) {

              Outer out = new Outer();

              Inner inner = out.getInner(2);

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

       }

}

interface Inner {//实现的接口

       int getNumber();

}

从别处偷来的图

相关文章

  • 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/xpztpctx.html