转-Cannot refer to an instance field arg while explicitly invoking a constructor

本文探讨了Java中构造器调用机制的问题,特别是在使用final字段时遇到的编译错误。通过一个具体例子展示了如何避免在构造器中直接引用实例变量,并提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

编译失败:

Cannot refer to an instance field arg while explicitly invoking a constructor  调用方法时不能引用一个实例变量

 

 1 package arkblue.lang.javapuzzler.n53;
 2 
 3 class Thing {
 4     public Thing(int i) {
 5 
 6     }
 7 }
 8 
 9 public class MyThing extends Thing {
10     private final int arg;
11 
12     public MyThing() {
13         super(arg = Math.round(12L)); //编译失败
14     }
15 
16 }

解决办法:使用了交替构造器调用机制(alternate constructor invocation)

在这个私有构造器中,表达式SomeOtherClass.func()的值已经被捕获到了变量i中,并且它可以在超类构造器返回之后存储到final类型的域arg中

 1 class SomeOtherClass {
 2     static int func() {
 3         return Math.round(12L);
 4     }
 5 }
 6 
 7 public class MyThing extends Thing {
 8     private final int arg;
 9 
10     public MyThing() {
11         this(SomeOtherClass.func());
12     }
13 
14     private MyThing(int i) {
15         super(i);
16         arg = i;
17     }
18 }

 

### 解决 Go 语言中未导出字段 `convListMap` 的问题 在 Go 中,如果遇到错误提示 “unexported field 'convListMap' in struct literal of type 'usermail_manager.ConvListMng'”,这通常意味着尝试直接访问或修改了一个私有(即首字母小写)字段。Go 编程语言严格遵循大小写敏感的可见性规则:大写字母开头的名字是导出的,可以被其他包访问;而小写字母开头的名字是非导出的。 为了修正此问题,有两种主要方法: #### 方法一:通过公共接口操作 创建一组公开的方法来设置和获取这些内部状态变量。这种方法不仅保持了封装原则还提供了更好的抽象层次[^1]。 ```go package usermail_manager type ConvListMng struct { convListMap map[string]string // 假设这是实际的数据结构 } func NewConvListMng() *ConvListMng { return &ConvListMng{ convListMap: make(map[string]string), } } // 添加一个用于更新 convListMap 的函数 func (m *ConvListMng) SetConvList(key, value string) { m.convListMap[key] = value } ``` 这样,在外部调用时就可以使用如下方式间接地改变该字段的内容而不违反 Go 的命名约定: ```go manager := usermail_manager.NewConvListMng() manager.SetConvList("exampleKey", "exampleValue") ``` #### 方法二:重构数据模型 另一种解决方案可能是重新设计类定义本身,使得那些需要共享给外界的状态成为公有的成员变量。然而这样做可能会破坏原有的封装机制并引入潜在的安全隐患,因此一般不推荐除非确实有必要让某些属性完全开放读取权限[^2]。 对于涉及不同位宽单元间交互的情况,如32位与64位系统的兼容性问题,则需特别注意注册表键路径以及API调用参数传递过程中可能出现的数据截断风险。不过这个问题与当前讨论的主题关系不大。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值