lombok @Builder(toBuilder = true) 在子 class 的构造函数上使用时出现编译错误
lombok @Builder(toBuilder = true) compilation error when used on constructor of a sub class
我的代码如下
package test.lombok;
import lombok.*;
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class SuperClass {
private int foo;
@Getter
public static class SubClass extends SuperClass {
private int bar;
@Builder(toBuilder = true)
private SubClass(int foo, int bar) {
super(foo);
this.bar = bar;
}
}
}
如上所示,我正在尝试在子 class.
上使用 @Builder(toBuilder = true)
当toBuilder设置为false时,完全没有问题
但是当我设置 toBuilder = true 时,出现编译错误 "Error:java: foo has private access in test.lombok.SuperClass"。
我想知道为什么会发生这种情况以及如何解决这个问题。
问题是因为 toBuilder
方法在 SubClass
中的实现方式:
public SuperClass.SubClass.SubClassBuilder toBuilder() {
return (new SuperClass.SubClass.SubClassBuilder()).foo(this.foo).bar(this.bar);
}
而不是 this.foo
应该是 super.foo
,并且代码可以编译。在这种情况下访问 super.foo
是可能的,因为 SubClass
是 SuperClass
的内部 class,否则,Java 也会不允许 super.foo
。
如果你想自己看lombok生成的代码,声明foo
为public,然后编译,然后delombok(或反编译),你会看到这样的代码(然后将 属性 更改为 private 以查看错误发生的位置):
import java.beans.ConstructorProperties;
public class SuperClass {
public int foo;
@ConstructorProperties({"foo"})
protected SuperClass(int foo) {
this.foo = foo;
}
public int getFoo() {
return this.foo;
}
public static class SubClass extends SuperClass {
private int bar;
private SubClass(int foo, int bar) {
super(foo);
this.bar = bar;
}
public static SuperClass.SubClass.SubClassBuilder builder() {
return new SuperClass.SubClass.SubClassBuilder();
}
public SuperClass.SubClass.SubClassBuilder toBuilder() {
return (new SuperClass.SubClass.SubClassBuilder()).foo(this.foo).bar(this.bar);
}
public int getBar() {
return this.bar;
}
public static class SubClassBuilder {
private int foo;
private int bar;
SubClassBuilder() {
}
public SuperClass.SubClass.SubClassBuilder foo(int foo) {
this.foo = foo;
return this;
}
public SuperClass.SubClass.SubClassBuilder bar(int bar) {
this.bar = bar;
return this;
}
public SuperClass.SubClass build() {
return new SuperClass.SubClass(this.foo, this.bar);
}
public String toString() {
return "SuperClass.SubClass.SubClassBuilder(foo=" + this.foo + ", bar=" + this.bar + ")";
}
}
}
}
编辑: 感谢@maaartinus 将我指向 super.foo
,答案已更新为该信息。
当属性 toBuilder 在注释 @Builder 中设置为 true。方法returnsSubClassBuilderclass。这是 toBuilder 方法的样子,
public SuperClass.SubClass.SubClassBuilder toBuilder() {
return (new SuperClass.SubClass.SubClassBuilder())
.foo(this.foo).bar(this.bar);
}
如您所见,toBuilder 方法尝试直接访问 foo 属性,而不是通过方法 getFoo.由于 foo 是私有的并且属于父类 class,SuperClass,您会得到以下错误:
错误:java:foo 在 test.lombok.SuperClass
中具有私有访问权限
据我所知,这是一个 Lombok 错误。有三种方法,如何访问 foo
并且只有其中一种有效:
- 普通
foo
导致 "Cannot make a static reference to the non-static field foo"
Lombok 使用的 this.foo
导致 "The field SuperClass.foo is not visible"
super.foo
有效!
AFAIK 在同一源文件中声明的所有内容 都可以访问以某种方式,但是找到正确的表达式可能很棘手。
从 Lombok 1.18.12 开始,您可以使用新的实验性功能 @SuperBuilder
.
支持toBuilder
:
import lombok.*;
import lombok.experimental.SuperBuilder;
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@ToString // For demonstration purposes only; only used in the main method.
@SuperBuilder(toBuilder = true)
public class SuperClass {
private int foo;
@Getter
@ToString(callSuper = true) // For demonstration purposes only; only used in the main method.
@SuperBuilder(toBuilder = true)
public static class SubClass extends SuperClass {
private int bar;
private SubClass(int foo, int bar) {
super(foo);
this.bar = bar;
}
}
public static void main(String[] argv) {
SubClass sc = SubClass.builder()
.foo(1)
.bar(2)
.build();
System.out.println(sc);
}
}
打印:
SuperClass.SubClass(super=SuperClass(foo=1), bar=2)
我的代码如下
package test.lombok;
import lombok.*;
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class SuperClass {
private int foo;
@Getter
public static class SubClass extends SuperClass {
private int bar;
@Builder(toBuilder = true)
private SubClass(int foo, int bar) {
super(foo);
this.bar = bar;
}
}
}
如上所示,我正在尝试在子 class.
上使用 @Builder(toBuilder = true)当toBuilder设置为false时,完全没有问题
但是当我设置 toBuilder = true 时,出现编译错误 "Error:java: foo has private access in test.lombok.SuperClass"。
我想知道为什么会发生这种情况以及如何解决这个问题。
问题是因为 toBuilder
方法在 SubClass
中的实现方式:
public SuperClass.SubClass.SubClassBuilder toBuilder() {
return (new SuperClass.SubClass.SubClassBuilder()).foo(this.foo).bar(this.bar);
}
而不是 this.foo
应该是 super.foo
,并且代码可以编译。在这种情况下访问 super.foo
是可能的,因为 SubClass
是 SuperClass
的内部 class,否则,Java 也会不允许 super.foo
。
如果你想自己看lombok生成的代码,声明foo
为public,然后编译,然后delombok(或反编译),你会看到这样的代码(然后将 属性 更改为 private 以查看错误发生的位置):
import java.beans.ConstructorProperties;
public class SuperClass {
public int foo;
@ConstructorProperties({"foo"})
protected SuperClass(int foo) {
this.foo = foo;
}
public int getFoo() {
return this.foo;
}
public static class SubClass extends SuperClass {
private int bar;
private SubClass(int foo, int bar) {
super(foo);
this.bar = bar;
}
public static SuperClass.SubClass.SubClassBuilder builder() {
return new SuperClass.SubClass.SubClassBuilder();
}
public SuperClass.SubClass.SubClassBuilder toBuilder() {
return (new SuperClass.SubClass.SubClassBuilder()).foo(this.foo).bar(this.bar);
}
public int getBar() {
return this.bar;
}
public static class SubClassBuilder {
private int foo;
private int bar;
SubClassBuilder() {
}
public SuperClass.SubClass.SubClassBuilder foo(int foo) {
this.foo = foo;
return this;
}
public SuperClass.SubClass.SubClassBuilder bar(int bar) {
this.bar = bar;
return this;
}
public SuperClass.SubClass build() {
return new SuperClass.SubClass(this.foo, this.bar);
}
public String toString() {
return "SuperClass.SubClass.SubClassBuilder(foo=" + this.foo + ", bar=" + this.bar + ")";
}
}
}
}
编辑: 感谢@maaartinus 将我指向 super.foo
,答案已更新为该信息。
public SuperClass.SubClass.SubClassBuilder toBuilder() {
return (new SuperClass.SubClass.SubClassBuilder())
.foo(this.foo).bar(this.bar);
}
如您所见,toBuilder 方法尝试直接访问 foo 属性,而不是通过方法 getFoo.由于 foo 是私有的并且属于父类 class,SuperClass,您会得到以下错误:
错误:java:foo 在 test.lombok.SuperClass
中具有私有访问权限据我所知,这是一个 Lombok 错误。有三种方法,如何访问 foo
并且只有其中一种有效:
- 普通
foo
导致 "Cannot make a static reference to the non-static field foo"
Lombok 使用的 this.foo
导致 "The field SuperClass.foo is not visible"super.foo
有效!
AFAIK 在同一源文件中声明的所有内容 都可以访问以某种方式,但是找到正确的表达式可能很棘手。
从 Lombok 1.18.12 开始,您可以使用新的实验性功能 @SuperBuilder
.
支持toBuilder
:
import lombok.*;
import lombok.experimental.SuperBuilder;
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@ToString // For demonstration purposes only; only used in the main method.
@SuperBuilder(toBuilder = true)
public class SuperClass {
private int foo;
@Getter
@ToString(callSuper = true) // For demonstration purposes only; only used in the main method.
@SuperBuilder(toBuilder = true)
public static class SubClass extends SuperClass {
private int bar;
private SubClass(int foo, int bar) {
super(foo);
this.bar = bar;
}
}
public static void main(String[] argv) {
SubClass sc = SubClass.builder()
.foo(1)
.bar(2)
.build();
System.out.println(sc);
}
}
打印:
SuperClass.SubClass(super=SuperClass(foo=1), bar=2)