Dart中实例化新对象为何修改旧对象?如何避免?
实例化同类型对象为何会修改旧对象的属性?如何避免?
运行以下Dart代码时,后续创建SampleClass的新实例会导致旧实例a的属性值被修改,具体代码和输出如下:
原代码
void main() { SampleClass a = SampleClass(publicParam: 'A'); print('1. a: ${a.getPrivateProperty}'); SampleClass b = SampleClass(publicParam: 'B'); print('2. a: ${a.getPrivateProperty}'); print('3. b: ${b.getPrivateProperty}'); SampleClass(publicParam: 'C'); print('4. a: ${a.getPrivateProperty}'); print('5. b: ${b.getPrivateProperty}'); } class SampleClass { final String publicParam; static late String _privateProperty; SampleClass({ required this.publicParam, }) { _privateProperty = publicParam; } // Getter String get getPrivateProperty => _privateProperty; }
原输出
1. a: A 2. a: B 3. b: B 4. a: C 5. b: C
原因分析
问题核心在于_privateProperty的static修饰符:
- Dart中,static成员变量属于类本身,而非类的实例,所有该类的实例共享同一个static变量的内存空间。
- 每次调用
SampleClass的构造函数时,都会把传入的publicParam赋值给这个共享的_privateProperty。 - 所有实例的
getPrivatePropertygetter返回的都是这个类级别的静态变量值,所以新实例创建时修改它,会导致所有旧实例的属性读取结果同步变化。
解决方法
去掉_privateProperty的static修饰符,让它成为实例级成员变量,每个实例会独立持有自己的_privateProperty副本,互不干扰:
修改后的代码
void main() { SampleClass a = SampleClass(publicParam: 'A'); print('1. a: ${a.getPrivateProperty}'); SampleClass b = SampleClass(publicParam: 'B'); print('2. a: ${a.getPrivateProperty}'); print('3. b: ${b.getPrivateProperty}'); SampleClass(publicParam: 'C'); print('4. a: ${a.getPrivateProperty}'); print('5. b: ${b.getPrivateProperty}'); } class SampleClass { final String publicParam; late String _privateProperty; // 移除static修饰符 SampleClass({ required this.publicParam, }) { _privateProperty = publicParam; } // Getter String get getPrivateProperty => _privateProperty; }
修改后的输出
1. a: A 2. a: A 3. b: B 4. a: A 5. b: B
此时每个实例的_privateProperty都是独立的,新实例的创建不会影响旧实例的属性值。
内容的提问来源于stack exchange,提问作者Ray Tres
相关产品推荐
相关产品推荐

