# OnJava8-Examples **Repository Path**: jiutian777/on-java8-examples ## Basic Information - **Project Name**: OnJava8-Examples - **Description**: study - **Primary Language**: Java - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-01-02 - **Last Updated**: 2024-02-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OnJava8 ## 11.内部类 ### 普通内部类 1. 对象中隐式地保留了一个引用,指向创建该对象的外部类对象。 ### 静态内部类(嵌套类) 1. 普通内部类中不能有 static 数据、static 字段,也不能包含嵌套类 ### 匿名内部类 1. 如果你正在定义一个匿名类,而且一定要用到一个在该匿名类之外定义的对象,编译器要求参数引用用 final 修饰,或者是“实际上的最终变量”。这里不写 final 也没有任何问题,但把它写上当作提醒通常更好。 ```java public class Parcel9 { public Destination destination(final String dest) { return new Destination() { private String label = dest; @Override public String readLabel() { return label; } }; } } ``` 2. 如果必须执行某个类似构造器的动作,该怎么办呢?因为匿名类没有名字,所以不可能有命名的构造器。借助实例初始化,我们可以在效果上为匿名内部类创建一个构造器,但是,我们无法重载实例初始化部分,所以只能有一个这样的构造器。 ```java public class Parcel10 { public Destination destination(final String dest, final float price) { return new Destination() { private int cost; // 实例初始化 { cost = Math.round(price); if (cost > 100) System.out.println("Over budget!"); } private String label = dest; @Override public String readLabel() { return label; } }; } } ``` 3. 与普通的继承相比,匿名内部类有些局限性,因为它们要么是扩展一个类,要么是实现一个接口,但是两者不可兼得。而且就算要实现接口,也只能实现一个。 ### 为什么需要内部类 #### 多重实现继承 内部类完善了多重继承问题的解决方案。接口解决了一部分问题,但内部类实际上支持了 “多重实现继承”。也就是说,内部类实际上支持我们继承多个非接口类型。 ```java class D { } abstract class E { } class Z extends D { E makeE() { return new E() { }; } } ``` 如果不需要解决“多重实现继承”问题,你可以用其他任何你能想象到的方式来编码,不需要内部类。但是有了内部类,我们就可以获得如下这些额外的功能: 1. 内部类可以有多个实例,每个实例都有自己的状态信息,独立于外围类对象的信息。 2. 一个外围类中可以有多个内部类,它们可以以不同方式实现同一个接口,或者继承同一个类。 3. 内部类对象的创建时机不与外围类对象的创建捆绑到一起。 4. 内部类不存在可能引起混淆的“is-a”关系;它是独立的实体。 #### 闭包与回调 内部类 Closure 实现了 Incrementable,用来提供一个指回 Callee2 中的钩子,但这是一个安全的钩子。不管是谁获得这个Incrementable 引用,都只能调用 inclement,没有其他能力。 ```java class Callee2 extends MyIncrement { private int i = 0; @Override public void increment() { super.increment(); i++; System.out.println(i); } private class Closure implements Incrementable { @Override public void increment() { Callee2.this.increment(); } } Incrementable getCallbackReference() { return new Closure(); } } ``` #### 事件驱动系统 模版方法模式+命令模式:通过创建不同的 Event 子类来表达不同的动作,内部类支持在一个类内实现同一基类 Event 的多个派生版本。对于每一类动作,我们可以继承一个新的 Event 内部类,并在 action() 的实现中编写控制代码。 1. 控制框架的整个实现是在一个单独的类内创建的,从而封装了关于该实现的所有独特之处。内部类用来表达解决问题所必需的多种不同的 action。 2. 内部类可以避免这种实现变得过于笨拙,因为我们很容易访问外围类的任何成员。如果没有这种能力,代码可能会不好用,以至于你不得不去寻找替代方案。 ```java public class GreenhouseControls extends Controller { private boolean light = false; public class LightOn extends Event { @Override public void action() { light = true; } } public class LightOff extends Event { public void action() { light = false; } } private boolean water = false; public class WaterOn extends Event { @Override public void action() { water = true; } } public class WaterOff extends Event { @Override public void action() { water = false; } } private String thermostat = "Day"; public class ThermostatNight extends Event { @Override public void action() { thermostat = "Night"; } } public class ThermostatDay extends Event { @Override public void action() { thermostat = "Day"; } } public class Bell extends Event { @Override public void action() { addEvent(new Bell(delayTime.toMillis())); } } public class Restart extends Event { private Event[] eventList; public Restart(long delayTime, Event[] eventList) { super(delayTime); this.eventList = eventList; for (Event e : eventList) addEvent(e); } @Override public void action() { for (Event e : eventList) { e.start(); addEvent(e); } start(); addEvent(this); } } public static class Terminate extends Event { @Override public void action() { System.exit(0); } } } ``` ### 继承内部类 如下,默认构造器编译不通过,必须在构造器中传递一个指向其包围类对象的引用,且调用其 super() 方法。 ```java class WithInner { class Inner { } } public class InheritInner extends WithInner.Inner { // InheritInner() {} // Won't compile InheritInner(WithInner wi) { wi.super(); } public static void main(String[] args) { WithInner wi = new WithInner(); InheritInner ii = new InheritInner(wi); } } ``` ### 内部类可以被重写吗 当继承外围类时,内部类并没有额外的特殊之处。这两个内部类是完全独立的实体,分别在自己的命名空间中。 ```java class Egg { private Yolk y; protected class Yolk { public Yolk() { System.out.println("Egg.Yolk()"); } } Egg() { y = new Yolk(); } } public class BigEgg extends Egg { public class Yolk { public Yolk() { System.out.println("BigEgg.Yolk()"); } } public static void main(String[] args) { new BigEgg(); } } /* Output: Egg.Yolk() */ ``` 或者,显式地继承某个内部类,insertYolk()方法允许 BigEgg2 将它的 Yolk 对象 **向上转型** 为 Egg2 中的 y 引用,当 g() 调用 y.f() 时,用到的是 f() 的重写版本。 ```java class Egg2 { protected class Yolk { public Yolk() { System.out.println("Egg2.Yolk()"); } public void f() { System.out.println("Egg2.Yolk.f()"); } } private Yolk y = new Yolk(); Egg2() { System.out.println("New Egg2()"); } public void insertYolk(Yolk yy) { y = yy; } public void g() { y.f(); } } public class BigEgg2 extends Egg2 { public class Yolk extends Egg2.Yolk { public Yolk() { System.out.println("BigEgg2.Yolk()"); } @Override public void f() { System.out.println("BigEgg2.Yolk.f()"); } } public BigEgg2() { insertYolk(new Yolk()); } public static void main(String[] args) { Egg2 e2 = new BigEgg2(); e2.g(); } } /* Output: Egg2.Yolk() New Egg2() Egg2.Yolk() BigEgg2.Yolk() BigEgg2.Yolk.f() */ ``` ### 局部内部类 局部内部类的名字在方法外是无法使用的。局部内部类允许我们定义具名的构造器以及重载版本,而匿名类只能使用实例初始化。**局部内层类允许我们创建该类的多个对象**,**而匿名内部类通常用于返回该类的一个实例**。 ```java interface Counter { int next(); } public class LocalInnerClass { private int count = 0; Counter getCounter(final String name) { // 局部内部类: class LocalCounter implements Counter { LocalCounter() { // 局部内部类可以冇一个构造器 System.out.println("LocalCounter()"); } @Override public int next() { System.out.print(name); return count++; } } return new LocalCounter(); } Counter getCounter2(final String name) { return new Counter() { // 匿名内部类不能有其名的构造器 // 只冇一个实例初始化部分 { System.out.println("Counter()"); } @Override public int next() { System.out.print(name); return count++; } }; } } ``` ### 内部类标识符 ```txt LocallnnerClass.java Counter.class 接口类 LocalInnerClass$l.class 匿名内部类 LocallnnerClass$lLocalCounter.class 局部内部类 LocallnnerClass.class 外围类(主类) ``` ## 12.集合 ## 14.流 ## 15.异常 ## 19.反射 ## 20.泛型