匿名内部类
当我们在编写1个类的代码时。
假如这个类名是A, 如果在A的某个方法内我们需要调用某个接口 or 抽象类 的实例的某个方法,通常我们会使用匿名内部类
例如:
public class A {private InterfaceB proxy;private setProxy(InterfaceB b) {this.proxy = b;}private void doIt() {this.proxy.doit()} public void process(){this.setProxy(new InterfaceB() {@Overridepublic void doIt(String x){log.info(x);}});this.doIt();}
}
lambda
后来jdk 8后我们也可以使用lambda 代码更简洁了
例如:
public class A {private InterfaceB proxy;private setProxy(InterfaceB b) {this.proxy = b;}private void doIt() {this.proxy.doit()} public void process(){this.setProxy(x->log.info(x););this.doIt();}
}
至于lambda 的简洁写法, 请参考 这里
非静态内部类
但是不排除某些程序员更喜欢编写显式内部类
例如:
java
public class A {private InterfaceB proxy;private void setProxy(InterfaceB b) {this.proxy = b;}private void doIt() {this.proxy.doIt();}public void process() {this.setProxy(new B());this.doIt();}//Explicit inernal classclass B implements InterfaceB {@Overridepublic void doIt() {System.out.println("Doing it");}}
}
至少更容易让初级程序员看懂. 这个很重要
静态内部类
但也有人推荐用静态内部类实现
java
public class A {private InterfaceB proxy;private void setProxy(InterfaceB b) {this.proxy = b;}private void doIt() {this.proxy.doIt();} public void process() {this.setProxy(new B());this.doIt();}//Explicit inernal classstatic class B implements InterfaceB {@Overridepublic void doIt() {System.out.println("Doing it");}}
}
咋看只有1个static 关键字的区别, 但就这样吗?
静态内部类与非静态内部类的区别
- 静态内部类只能访问外层类的静态成员, 不能访问非静态成员
- 非静态内部类, 能被其他类直接实例化(假如 有足够访问级别,例如设成public) , 而非静态类假如能被其他类访问, 则必须实例化外层类, 再实例化非静态内部类。
例子:
OuterClass
@Slf4j
public class OuterClass {private static int outerStaticVar = 10;private int outerNonStaticVar = 20;static class StaticInnerClass {public void print() {log.info("Outer static variable: " + outerStaticVar); // able to access static members of outer class// log.info("Outer non-static variable: " + outerNonStaticVar); // Error, cannot access non-static members of outer class}}class InnerClass {public void print() {log.info("Outer static variable: " + outerStaticVar); // able to access static members of outer classlog.info("Outer non-static variable: " + outerNonStaticVar); // able to access non-static members of outer class as well}}
}
其他类:
@Slf4j
public class OtherClass {public static void main(String[] args){log.info("StaticClass...");OuterClass.StaticInnerClass sinClass= new OuterClass.StaticInnerClass(); // can new static internal class directlysinClass.print();OuterClass.InnerClass inClass = new OuterClass().new InnerClass(); // must new OuterClass firstinClass.print();}}
静态内部类与非静态内部类的使用场景
当内部类不需要访问外部类的实例成员时,且希望内部类与外部类之间没有直接的绑定关系时,可以考虑使用静态内部类。例如,当内部类只是作为外部类的辅助类或工具类时,不需要直接访问外部类的实例状态,这时静态内部类更合适。
当内部类需要访问外部类的实例成员,并且需要与外部类紧密关联时,可以考虑使用非静态内部类。非静态内部类可以直接访问外部类的所有成员,包括静态和非静态成员,可以方便地共享外部类的状态和行为。
需要根据具体的设计需求和场景来选择合适的内部类类型。在许多情况下,内部类的选择更多地取决于代码组织和可读性的考虑,以及是否需要对外部类进行封装和隐藏。