我遇到的情况是,我无法更改一组类的主要 API,但我需要从文件数据构造一个新实例,包括设置大量私有(private)字段。
到目前为止,我的想法是创建一个静态工厂方法,该方法将从文件中生成我的实例,如下所示:
版本 1:
public class Item {
private Long id;
public static Item fromArchived(final ArchivedItem archived) {
return new Item(){{
this.id = archived.getId();
}};
}
}
IntelliJ IDEA 没有给我红线,我不知道有什么问题,直到我运行我的 Maven 构建,结果是:
error: id has private access in Item
相比之下,这有效:
版本 2:
public class Item {
private Long id;
public static Item fromArchived(final ArchivedItem archived) {
Item item = new Item(){{
// this.id = archived.getId();
}};
item.id = archived.getId();
return item;
}
}
我一直在审查我的 core Java knowledge ,而我对为什么版本 1 不起作用的唯一模糊猜测是实例初始化程序(双括号初始化)以某种方式出现在静态上下文中,这也没有任何意义。想法?
编辑
我认为问题的最初形式很模糊。我正在寻找的答案解释了为什么我在静态方法的主体中可以看到父级的私有(private) id
字段,但在实例初始化程序的主体中却失去了它的可见性同一静态方法内的匿名子类。
最佳答案
其他答案都是准确的,但这是我的看法。
public class Item {
private Long id;
public static Item fromArchived(final ArchivedItem archived) {
return new Item(){{
this.id = archived.getId();
}};
}
}
这里静态方法生成一个扩展 Item 的匿名类。 Item$id 将对这个匿名类隐藏。
以下代码片段与前面的代码片段等效,但作为一个命名嵌套类,公开构造函数方法而不是调用构造函数的方法。
public class Item {
private Long id;
class FromArchived extends Item {
public FromArchived(final ArchivedItem archived) {
this.id = archived.getId();
}
}
}
无论访问是来自命名类、嵌套类还是匿名类,可见性修饰符都会一致地强制执行。
最后,下面的代码片段应该在类内部工作,您可以完全访问该类的所有私有(private)字段和方法。
public class Item {
private Long id;
public static Item fromArchived(final ArchivedItem archived) {
Item item = new Item();
item.id = archived.getId();
return item;
}
}
无论您使用的是构造函数、方法还是静态方法,都是如此。
关于Java:匿名内部类实例初始化程序访问外部类私有(private)成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23085736/