Android开发:Bundle状态保存与final变量相关技术疑问
首先得先澄清一个关键误解:你并没有把要保留的文本值存入那个final变量TEXT_CONTENTS里——这个变量只是作为Bundle存储数据时的键名(字符串常量),真正要保存的文本是存在系统提供的Bundle对象中的,和这个final变量本身没有存储关系。接下来逐个拆解你的疑问:
1. 若变量为final,后续如何存入需要保留的文本值?
你完全不用往这个final变量里存值!咱们看你的代码:
// 这只是定义了一个固定不变的字符串常量,值是"TextContents" private final String TEXT_CONTENTS = "TextContents"; // 保存数据时,是把文本存入Bundle对象,用TEXT_CONTENTS作为键名 outState.putString(TEXT_CONTENTS, textView.getText().toString());
final修饰的TEXT_CONTENTS是一个字符串常量,它的作用只是提供一个固定的键名,让你能准确地在Bundle中定位要保存/读取的数据。你真正要保存的文本是存在outState这个Bundle实例里的,和TEXT_CONTENTS这个变量无关——这个变量只是帮你告诉系统:“我要把文本存在叫TextContents的这个位置”。
你提到的维基百科对final的定义是完全正确的:这个变量的引用(也就是它的值"TextContents")不能被修改,但这完全不影响我们往Bundle里存不同的文本值,因为我们根本没动这个变量本身。
2. 将需保留的值存入final变量的核心作用是什么?
准确说,不是“把值存入final变量”,而是用final常量作为Bundle的键名,核心作用有这几个:
- 避免拼写错误:如果直接用字符串字面量
"TextContents",万一在onRestoreInstanceState里写成了"TextContent"(少个s),编译时不会报错,但运行时会找不到数据。用final常量的话,IDE会自动补全,写错了会直接提示错误,编译就通不过,提前避免bug。 - 统一管理键名:如果你的代码里多处用到这个键(比如后续加其他地方读取这个值),只需要修改
TEXT_CONTENTS的定义,所有引用的地方都会同步更新,不用挨个找字符串字面量修改。 - 防止意外修改键名:
final修饰后,这个键名不会被代码意外修改(比如不小心赋值TEXT_CONTENTS = "NewKey"),保证保存和读取时用的是同一个键。
3. 程序执行结束后所有变量会被销毁,为何存入此类变量仍能保留数据?
还是那个核心关键点:数据根本没存在这个final变量里!当系统要销毁Activity时(比如休眠唤醒、旋转屏幕),onSaveInstanceState方法会被调用,你把文本存入系统传递过来的outState Bundle对象中——这个Bundle是由Android系统负责保存的,它会被序列化后存在系统的内存或者磁盘里,和你的Activity实例以及其中的变量无关。
当Activity恢复时,系统会把这个保存好的Bundle再传递给onRestoreInstanceState或者onCreate方法,你用TEXT_CONTENTS这个键名去Bundle里取出之前保存的文本——这时候原来的Activity实例已经被销毁了,TEXT_CONTENTS这个变量是新的Activity实例里的新变量,但它的值还是"TextContents",所以能准确找到对应的数据。
简单说:final变量只是个“钥匙的名字”,真正的“数据箱子”是系统保存的Bundle,钥匙名字不变,就能打开同一个箱子取数据。
内容的提问来源于stack exchange,提问作者Ubiux

