JAVA内部类简单使用


内部类:一个类的内部定义的类
外部类:拥有内部类的类

成员内部类又分为静态成员内部内和非静态成员内部类
局部内部类可以位于方法内、块内、构造器内
成员内部类:分为成员内部类和局部内部类

成员内部类

(1) 成员内部类可以访问外部类的所有内容,包括静态和非静态的都可以访问
(2)静态成员内部类只能访问外部类的静态成员、静态方法,因为静态内部类是不依赖实例对象的,即便实例对象不存在也能运行,因此静态的只能访问静态的,避免出现问题

class Demo {
    
    

    private static String dept;
    private String name;

    class InnerDemo {
    
    
        public void InnerFunc() {
    
    
            System.out.println("外部类的静态和非静态成员变量" + name + dept);
            outerFunc();
            outerStaticFunc();
        }
    }
    /**
     * 静态类是不依赖实例对象的,即便实例对象不存在也能运行,因此静态的只能访问静态的,避免出现问题
     */
    static class StaticInnerDemo {
    
    
        public void InnerFunc() {
    
    
            System.out.println("只能访问外部类的静态方法和变量:" + dept);
            outerStaticFunc();
        }
    }
    
    public void outerFunc() {
    
    
        System.out.println("外部类非静态方法");
    }

    public static void outerStaticFunc() {
    
    
        System.out.println("外部类静态方法");
    }
}

(3)外部类不能直接访问内部类的成员变量和方法,因为作用域不同,但可以通过内部类的实例对象进行调用,或者通过静态内部类.静态方法和成员变量进行调用

class Demo {
    
    

    private static String dept;
    private String name;

    class InnerDemo {
    
    
        public void InnerFunc() {
    
    
            StaticInnerDemo.staticInnerFunc();
            new StaticInnerDemo().InnerFunc();
        }
    }

    /**
     * 静态类是不依赖实例对象的,即便实例对象不存在也能运行,因此静态的只能访问静态的,避免出现问题
     */
    static class StaticInnerDemo {
    
    
        public void InnerFunc() {
    
    
            System.out.println("只能访问外部类的静态方法和变量:" + dept);
            outerStaticFunc();
        }

        public static void staticInnerFunc() {
    
    
            System.out.println("内部类静态方法");
        }
    }

(4)内部类和外部类的变量名相同,调用方式如下:

class Demo {
    
    
    private int num = 10;
    class InnerDemo {
    
    
        private int num = 20;
        public void InnerFunc() {
    
    
            int num = 30;
            System.out.println(num); //30  就近原则
            System.out.println(this.num);//20
            System.out.println(Demo.this.num);//10
        }
    }
}

(5) 静态和非静态内部类对象的创建方式如下:

public class Main {
    
    
    public static void main(String[] args) {
    
    
        //非静态内部类创建方式
        Demo demo = new Demo();
        Demo.InnerDemo innerDemo = demo.new InnerDemo();
        System.out.println(innerDemo);
        //静态内部类创建方式
        Demo.StaticInnerDemo staticInnerDemo = new Demo.StaticInnerDemo();
        System.out.println(staticInnerDemo);
    }
}

局部内部类

  • 方法内的内部类【包括匿名内部类】使用的局部变量,必须是final修饰,1.8之前的JDK必须在局部变量前加final修饰,1.8版本开始final修饰符可以省略。
    原因: 因为局部变量会随着方法的调用结束而消失,局部内部类对象并没有立马从堆内存中消失,还需要使用这个变量,为了让这个局部变量的数据还能继续被使用,就使用final修饰,这样堆内存中会存储这个常量值。常量在类编译时期载入常量池中。
public class Main {
    
    
    public static void main(String[] args) {
    
    
        int i = 100;
        class Demo {
    
    
            public void test() {
    
    
                System.out.println(i);
            }
        }
        //局部内部类,必须先定义再使用
        new Demo().test();
    }
}
  • 如果某个类只在某个方法中使用一次,就可以使用局部内部类

匿名内部类实际就是内部类简化写法,只要存在一个类或接口就可以使用

匿名内部类实际就是局部内部类的定义和对象创建过程的代码集合

public class TestA {
    
    
	@Test
	public void test(){
    
    
		int j=10;
		Runnable a=new Runnable() {
    
    
			@Override
			public void run() {
    
    
				//j=100;//此处不能这些写,匿名内部类方法访问外层的局部变量,要求局部变量必须是final修饰的
				System.out.println(j);
			}
		};
		a.run();
	}
}

类中定义接口

  • 内部接口不管有没有修饰static,都是static修饰的
  • 一般而言,内部接口更多的是针对类的内部使用,但普通接口一般是公有接口,我们可以内部接口是对类或接口的进一步逻辑拆分,如JDK接口Map中的内部接口Entry

猜你喜欢

转载自blog.csdn.net/user2025/article/details/108960979