Java中处理受保护嵌套类的列表

Java中处理受保护嵌套类的列表

在Java中,访问受保护的嵌套类会受到一定的限制,尤其是在不同的包中。当需要在一个包外的类中创建并操作另一个包中类的受保护嵌套类列表时,直接访问通常是不允许的。本文将介绍一种解决此问题的方法:通过定义公共接口并让嵌套类实现该接口。

问题背景

假设我们有以下两个类,SomeClass位于stuff包中,包含一个受保护的嵌套类Nested。MyClass位于project包中,需要创建一个Nested类的列表。

// SomeClass.java
package stuff;

public class SomeClass {
  protected class Nested {
    int x;
    public Nested setX(int arg) {
      x = arg;
      return this;
    }
    public int getX() {
      return x;
    }
  }

  public Nested make(int x) {
    return new Nested().setX(x);
  }
}
// MyClass.java
package project;

import java.util.List;
import java.util.ArrayList;
import stuff.SomeClass;

public class MyClass {
  public SomeClass instance;

  public List method() {
    var list = new ArrayList<>();
    list.add(instance.make(1));
    list.add(instance.make(2));
    return list; // ... to return an ArrayList
  }
}

直接在MyClass中创建ArrayList是不允许的,因为Nested类是受保护的,且MyClass位于不同的包中。

解决方案:定义公共接口

为了解决这个问题,我们可以在SomeClass中定义一个公共接口,并让Nested类实现该接口。然后,我们可以在MyClass中使用该接口来声明列表。

  1. 定义接口: 在SomeClass中定义一个公共接口NestedInterface。
// SomeClass.java
package stuff;

public class SomeClass {

  public interface NestedInterface {
    int getX();
  }

  protected class Nested implements NestedInterface{
    int x;
    public Nested setX(int arg) {
      x = arg;
      return this;
    }
    public int getX() {
      return x;
    }
  }

  public Nested make(int x) {
    return new Nested().setX(x);
  }
}
  1. 修改make()方法: 修改make()方法的返回类型为NestedInterface。
// SomeClass.java
package stuff;

public class SomeClass {

  public interface NestedInterface {
    int getX();
  }

  protected class Nested implements NestedInterface{
    int x;
    public Nested setX(int arg) {
      x = arg;
      return this;
    }
    public int getX() {
      return x;
    }
  }

  public NestedInterface make(int x) {
    return new Nested().setX(x);
  }
}
  1. 在MyClass中使用接口: 在MyClass中使用NestedInterface来声明列表。
// MyClass.java
package project;

import java.util.List;
import java.util.ArrayList;
import stuff.SomeClass;
import stuff.SomeClass.NestedInterface;

public class MyClass {
  public SomeClass instance;

  public List method() {
    var list = new ArrayList();
    list.add(instance.make(1));
    list.add(instance.make(2));
    return list;
  }
}

完整代码

// SomeClass.java
package stuff;

public class SomeClass {

  public interface NestedInterface {
    int getX();
  }

  protected class Nested implements NestedInterface{
    int x;
    public Nested setX(int arg) {
      x = arg;
      return this;
    }
    public int getX() {
      return x;
    }
  }

  public NestedInterface make(int x) {
    return new Nested().setX(x);
  }
}
// MyClass.java
package project;

import java.util.List;
import java.util.ArrayList;
import stuff.SomeClass;
import stuff.SomeClass.NestedInterface;

public class MyClass {
  public SomeClass instance;

  public List method() {
    var list = new ArrayList();
    list.add(instance.make(1));
    list.add(instance.make(2));
    return list;
  }
}

总结

通过定义公共接口并让受保护的嵌套类实现该接口,我们可以绕过访问限制,从而在不同的包中安全地操作嵌套类的实例。这种方法不仅解决了访问权限的问题,还提高了代码的灵活性和可维护性。在设计API时,可以考虑使用这种模式来隐藏内部实现细节,同时提供对外部世界的受控访问。