我可以从静态内部类访问外部类的字段吗?
Posted
技术标签:
【中文标题】我可以从静态内部类访问外部类的字段吗?【英文标题】:Can I access an outer class's field from a static inner class? 【发布时间】:2021-04-21 16:55:44 【问题描述】:我有一个类有另一个static
内部类:
class A
private List<String> list;
public static class B
// I want to update list here without making list as static
// I don't have an object for outer class
【问题讨论】:
静态嵌套类没有对周围类的任何实例的隐式引用。您需要将引用传递给您希望它修改的实例。为什么 B 类是静态的? Class B 只是为 UI 显示生成一个模板结构,现在我正在执行一些操作来获取值,并且需要设置为周围的类。这是设计问题吗? 如果您需要每个 B 实例与特定的 A 实例相关联,并且能够对其进行操作,最简单的解决方案是使 B 成为非静态的,并在构建时建立这种关系。 我可以将评论重新表述为“我没有 A,但我想更改它的列表”。这是否更明显地表明您的问题没有意义? 是的,我现在明白了。谢谢 【参考方案1】:当您不需要需要访问实例变量时,您通常会使用静态类。如果您需要访问实例变量,请使类成为非静态类。
【讨论】:
【参考方案2】:正如您从其他答案中看到的那样,您将需要一个非静态内部类来执行此操作。
如果你真的不能让你的内部类非静态,那么你可以在外部类中添加所需的 getter 和 setter 方法,并通过从内部静态类中创建外部类的实例来访问它们:
public class A
private List<String> list = new ArrayList<String>();
public List<String> getList()
return list;
public void setList(List<String> list)
this.list = list;
public static class B
// i want to update list here without making list as static
void updList()
A a = new A();
a.setList(someOtherList);
System.out.println(a.getList());
【讨论】:
这真的是一个解决方案,考虑到表达式A a = new A();
中的 A 类对象只是局部的,具有其初始值吗?请详细说明一下好吗?
你想用内部类做什么?
在此处添加 getter 和 setter 无关紧要,只需通过 a.list
访问该字段即可。关键是您创建了一个A
的新实例。但正如this comment 已经说过的,使用A
的临时实例没有持久效果。
因为它是一个静态内部类(并且list
是非静态的),我们需要一个显式实例来访问它,否则我们可以简单地使用A.this.list
【参考方案3】:
不,您需要一个非static
内部类来执行此操作。
来自JLS §8.5.1:
static
关键字可以修改非内部类或接口T
的主体内的成员类型C
的声明。它的作用是声明C
不是内部类。正如T
的静态方法在其主体中没有 T 的当前实例一样,C
也没有T
的当前实例,也没有任何词法封闭实例。如果
static
类包含封闭类的非静态成员的用法,则会出现编译时错误。
【讨论】:
【参考方案4】:在您的代码中,list
是类 A
的实例变量,B
是嵌套的静态类。对于嵌套的静态类,访问静态和非静态成员的规则不会改变。
list
是实例变量,因此无法从静态上下文中访问。
要启用此功能,您需要将静态嵌套类更改为内部类。
class A
private List<String> list = new ArrayList<String>();
public class B
public void someMethod()
list.add("abc");
【讨论】:
【参考方案5】:private List<String> list;
这里 list 是一个实例变量,而内部类是静态的,这意味着 class B 是在不同的 class A 实例中相同;无法访问它。而且,这也是一个非常好的和明显的原因。
您可以使用的一种解决方案是将成员 list 的引用传递给 class B 的构造函数weakReference 以避免内存泄漏。
类似这样的:
class A
private List<String> list;
public static class B
WeakReference<List<String>> innerList;
//constructor
B(WeakReference<List<String>> innerList)
this.innerList = innerList;
【讨论】:
以上是关于我可以从静态内部类访问外部类的字段吗?的主要内容,如果未能解决你的问题,请参考以下文章