Java中的内部类

一、总结

1.内部类简介
在一个类的内部重新定义一个新类就称为内部类。

内部类分为三种:
(1) 普通内部类:唯一好处就是可以方便的访问外部类的私有属性,同样外部类也可以方便的访问内部类的私有属性。

(2) 静态内部类:在普通内部类前面加static修饰。static内部类的唯一好处就是可以直接访问外部类的静态私有属性(相对于定义成外部类来说的)。

(3) 匿名内部类:假若一个类只使用一次,那么定义成匿名内部类比较省事。

使用:
普通内部类首先要实例化一个外部类对象,然后通过外部类对象实例化一个内部类对象。即使内部类中的所有的方法都没有访问外部类的属性,也需要遵守这个规则。
静态内部类可以直接通过“外部内.内部类 对象 = new 外部内.内部类()”来实例化对象,eg:Outer.Inner i = new Outer.Inner();

2.内部类加static修饰,此时这个内部类就变成了外部类,它变为只能访问外部类的static的属性(eg: private static int a;)。此时可以不通过外部类直接创建内部类。

3.所有的static内部类只能访问外部类的static属性。类的static属性无论类是否实例化了对象都是存在的。不能通过实例化的对象.new 一个静态内部类,因为静态内部类不属于任何一个对象

4.Android中大量使用static的内部类。

5.只有在内部类中才允许使用static修饰类,普通的类不可以是用static修饰。eg: 在一个类的内部是正确的,普通类是错误的 static class Stub { }

6. 内部类可声明成 public 或 private,当内部类声明成 public 或 private 时,对其访问的限制和成员变量和成员方法完全相同。

7. 内部类除了可以通过外部类访问外,还可以直接在其它类中进行调用,调用的基本格式:

外部类.内部类 内部类对象 = 外部类实例.new 内部类()
class Outer {
    private String info = "Hello World!";
    class Inner {
        public void print() {
            System.out.println(info);
        }
    }
}

public class InnerClassTest {
    public static void main(String args[]) {
        Outer o = new Outer();
        Outer.Inner i = o.new Inner();
        i.print();
    }
}

# java InnerClassTest 
Hello World!
# ls
InnerClassTest.class  InnerClassTest.java  Outer.class  Outer$Inner.class

8. 观察内部类的class文件,可以发现,内部类定义之后生成的class文件是以 "Outer$Inner.class" 的形式存在的,在Java中只要在文件中看见了 "$",则在程序中将其替换成 "."

9. 理论上,内部类可以定义在程序的任何位置,例如 代码块中、方法中。但是在方法中定义的内部类不能直接访问方法中的参数,如果方法中的参数想要被内部类访问,则参数前必须加上 final 关键字。注:JDK1.8 开始,即使不加 final 修饰也可以正常使用了。

class Outer {
    private String info = "Hello World!";
    void func(final String str) {
        class Inner {
            public void print() {
                System.out.println(info + str);
            }
        }
        new Inner().print();
    }
}

public class InnerClassTest {
    public static void main(String args[]) {
        new Outer().func(" Baby");
    }
}

# java InnerClassTest 
Hello World! Baby

10. 静态内部类ChatGPT问答

java中的static class的作用?

在 Java 中,使用 static 关键字定义类时,这个类就成为了静态内部类,被称为嵌套静态类(Nested Static Class)。静态内部类与普通内部类(即不含 static 关键字的内部类)有所不同,它具有以下特点:

1. 静态内部类是属于外部类的,但是它们的实例化是相互独立的,即可以直接通过外部类名访问它们,不需要先创建外部类的实例。

2. 静态内部类可以直接访问外部类的静态属性和方法,但不能访问外部类的非静态属性和方法。

3. 静态内部类与外部类之间的访问是单向的,即外部类不能访问静态内部类的成员,除非是静态的。

静态内部类通常用于隐藏一些不需要对外暴露的类和实现细节,从而实现更好的封装性和安全性。它还可以用于实现更好的代码组织结构和逻辑划分,使复杂的代码更容易维护和扩展。

此外,静态内部类还可以作为一种轻量级的“线程安全”的实现方式,因为它的实例化是相互独立的,不需要考虑多线程并发访问的问题。这使得静态内部类比较适合用于实现缓存、工厂模式等计算密集型的任务。

 

二、试验Demo

1. 内部类访问外部类私有属性,在类的外部使用内部类:

/*InnerDemo.java*/

class Outer {
    private int a = 10;
    class Inner {
        public void printInfo(){
            System.out.println("a = "+a);
        }
    }
    
}

public class InnerDemo {
    public static void main(String args[]) {
        Outer o = new Outer();
        Outer.Inner i = o.new Inner();
        i.printInfo();
    }
}

 

2. 静态内部类

/*InnerDemo2.java: Static Inner class*/

class Outer {
    private static int a = 10;
    static class Inner {
        public void printInfo(){
            System.out.println("a = "+a);
        }
    }
    
}

public class InnerDemo2 {
    public static void main(String args[]) {
        //Outer o = new Outer();
        //Outer.Inner i = o.new Inner(); //This is error of static inner class
        Outer.Inner i = new Outer.Inner();
        i.printInfo();
    }
}

 

3. 对于只使用一次的new时重写初始化

/*InnerDemo3.java: Anonymous inner class*/

interface A {
    public void printInfo();
}

class B implements A {
    public void printInfo() {
        System.out.println("Hello, world!");
    }
}


public class InnerDemo3 {
    public static void main(String args[])    {
        testFunc(new B());
        testFunc(new A(){ //new A()的同时进行实例化
            public void printInfo() {
                System.out.println("Hello, world2!");
            }
            });
    }

    public static void testFunc(A a) {
        a.printInfo();
    }
}

 

posted on 2019-02-24 10:53  Hello-World3  阅读(108)  评论(0编辑  收藏  举报

导航