当我们在编写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() {
@Override
public void doIt(String x){
log.info(x);
}
});
this.doIt();
}
}
后来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 class
class B implements InterfaceB {
@Override
public 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 class
static class B implements InterfaceB {
@Override
public void doIt() {
System.out.println("Doing it");
}
}
}
咋看只有1个static 关键字的区别, 但就这样吗?
@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 class
log.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 directly
sinClass.print();
OuterClass.InnerClass inClass = new OuterClass().new InnerClass(); // must new OuterClass first
inClass.print();
}
}
当内部类不需要访问外部类的实例成员时,且希望内部类与外部类之间没有直接的绑定关系时,可以考虑使用静态内部类。例如,当内部类只是作为外部类的辅助类或工具类时,不需要直接访问外部类的实例状态,这时静态内部类更合适。
当内部类需要访问外部类的实例成员,并且需要与外部类紧密关联时,可以考虑使用非静态内部类。非静态内部类可以直接访问外部类的所有成员,包括静态和非静态成员,可以方便地共享外部类的状态和行为。
需要根据具体的设计需求和场景来选择合适的内部类类型。在许多情况下,内部类的选择更多地取决于代码组织和可读性的考虑,以及是否需要对外部类进行封装和隐藏。