内部类(inner class),顾名思义,就是定义在一个类的内部。
内部类的特点:
1、内部类方法可以访问该类定义所在的作用域(外部类)中的数据,包括私有数据。
2、内部类可以对同一个包中的其他类隐藏起来(public类与默认修饰符的类在同一个包内都是可以被访问的)。
3、当想定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷(当然Java8中的lambda是个更好的选择)。
最简单的内部类实现:
/** * Created by N3verL4nd on 2016/11/28. */ class Outer{ private int x = 100; class Inner{ public void show(){ System.out.println(x); } } public void show(){ Inner inner = new Inner(); inner.show(); } } public class HelloWorld { public static void main(String[] args) { Outer outer = new Outer(); outer.show(); } }内部类的访问特点:
1、内部类可以直接访问外部类的成员。
2、外部类要访问内部类,必须建立内部类的对象。
内部类的一些特点:
1、内部类可以被成员修饰符所修饰(private, protected, public,static,默认修饰符),毕竟内部类在外部类成员函数的位置。其他类只能够被public与默认修饰符修饰。
2、普通的内部类不能有静态域和方法。
/** * Created by N3verL4nd on 2016/11/28. */ class Outer{ private int x = 100; private static int y = 200; //内部类可以被任意成员修饰符(private,protected,public,默认修饰符)修饰 public class Inner{ public void show(){ System.out.println("Inner::show..." + x); } } public static class StaticInner{ //如果内部类定义了静态成员,该内部类也必须是静态的。 public void print(){ System.out.println("StaticInner::print..." + y); } public static void show(){ System.out.println("StaticInner::show..." + y); } } public void show(){ Inner inner = new Inner(); inner.show(); } } public class HelloWorld { public static void main(String[] args) { Outer outer = new Outer(); outer.show(); //直接访问外部类中的内部类的成员 Outer.Inner inner = new Outer().new Inner(); inner.show(); //如果内部类是静态的,相当于一个外部类 Outer.StaticInner staticInner = new Outer.StaticInner(); staticInner.print(); Outer.StaticInner.show(); } }
当内部类不需要引用外部类的对象时,可以将内部类声明为静态内部类,以便取消产生的引用外部类的引用(外部类.this)。
举例:
/** * Created by N3verL4nd on 2016/11/28. */ class MinMax{ public static class Pair<T>{ private T first; private T second; public Pair(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public T getSecond() { return second; } } public static Pair getMinMax(int... arr){ if (arr == null || arr.length == 0) return null; int first = arr[0]; int second = arr[0]; for (int x : arr){ if (x < first) first = x; if (x > second) second = x; } return new Pair(first, second); } } public class HelloWorld { public static void main(String[] args) { int[] arr = {2, 5, 1, 3, 4}; MinMax.Pair pair = MinMax.getMinMax(arr); System.out.println(pair.getFirst() + " " + pair.getSecond()); } }
/** * Created by N3verL4nd on 2016/11/28. */ class Outer{ private int num = 3; class Inner{ private int num = 4; public void show1(){ int num = 5; System.out.println(num); } public void show2(){ System.out.println(this.num); } public void show3(){ System.out.println(Outer.this.num); } } } public class HelloWorld { public static void main(String[] args) { new Outer().new Inner().show1(); new Outer().new Inner().show2(); new Outer().new Inner().show3(); } }
因为内部类持有外部类的引用,所以内部类能够直接访问外部类的成员。
局部内部类:
局部内部类不能被public/private等修饰符修饰,它的作用于被限定在声明这个局部类的块中。
除method方法之外,没有任何方法知道Inner类的存在。
局部内部类不仅可以访问外部类的数据,还可以访问局部变量,但是必须用final修饰。
/** * Created by N3verL4nd on 2016/11/28. */ class Outer{ void method(){ //内部类在局部位置上只能访问局部中被final修饰的局部变量。 final int x = 100; class Inner{ void show(){ System.out.println(x); } } Inner inner = new Inner(); inner.show(); } } public class HelloWorld { public static void main(String[] args) { Outer outer = new Outer(); outer.method(); } }匿名内部类: