mutability and immutability

改变一个变量和改变一个变量的值的区别

        改变一个变量:将该变量指向另一个值的存储空间。

        改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值。

Immutability&Mutability

        根据我个人的理解,immutability就是在改变变量值的时候能够再申请一个新的空间,而mutability则是对于原存储空间中写入一个新的值。

为了保障安全性,mutability需要采用防御式拷贝,但是又未必需要做改动,因此会产生大量的内存浪费。immutability则不需要,因为每次改变都会重新生成一个新的对象。

典型的mutable类型为StringBuilder,典型的immutable类型为String。

String s="a";
s=s.concat("b");
StringBuilder sb=new StringBuilder("a");
sb.append("b");

final修饰符

final修饰的变量,如x,并不是其值不能够改变,而是x指向的区域不能够改变,但是区域内包含的值是可以改变的。

  1. final类无法派生子类
  2. final变量无法改变引用
  3. final方法无法被子类重写

### 解决 `Missing PendingIntent mutability flag` 问题 在 Android 开发中,当目标 SDK 设置为 Android 12 或更高版本时,如果未指定 `PendingIntent` 的可变性标志 (`FLAG_IMMUTABLE` 或 `FLAG_MUTABLE`),可能会遇到 lint 警告或运行时错误。此问题是由于 Android 平台的安全增强措施引入的。 #### 错误原因分析 Android 12 及以上版本要求开发者显式声明 `PendingIntent` 是否可以被修改。如果不设置这些标志,则会触发警告或异常[^2]。具体来说: - 如果应用程序尝试创建一个 `PendingIntent` 对象而没有指定其可变性标志,在某些情况下可能导致安全风险。 - 这种情况通常表现为以下 Lint 提示: **Warning: Missing PendingIntent mutability flag [UnspecifiedImmutableFlag]**. --- #### 解决方案 要解决这个问题,可以通过以下方法之一来修复代码中的问题: ##### 方法一:使用不可变 `PendingIntent` 对于大多数场景而言,推荐使用不可变的 `PendingIntent` (即带有 `FLAG_IMMUTABLE` 标志),因为它更安全并能防止意外行为发生。下面是一个例子展示如何实现这一点: ```java // 创建不可变的 PendingIntent 实例 PendingIntent pendingIntent = PendingIntent.getActivity( context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); // 添加 FLAG_IMMUTABLE ``` 这里的关键在于将 `PendingIntent.FLAG_IMMUTABLE` 加入到 flags 参数之中[^3]。 --- ##### 方法二:允许待定意图具有可变性 仅当你确实需要让接收方能够更改原始请求数据时才应该考虑这种方法;否则不建议这样做因为这可能带来安全隐患。下面是相应调整后的代码片段: ```java // 创建可变的 PendingIntent 实例 PendingIntent pendingIntent = PendingIntent.getBroadcast( context, requestCode, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_MUTABLE); // 使用 FLAG_MUTABLE ``` 注意这里的区别是我们加入了 `PendingIntent.FLAG_MUTABLE` 来表明该实例是可以改变的内容。 --- ##### 方法三:兼容旧版设备处理逻辑 为了支持低于 API Level 31 的设备同时满足新规定的要求,你可以采用条件判断的方式来动态选择合适的标记位组合方式如下所示: ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // 针对 Android 12+ 设备 pendingIntent = PendingIntent.getService(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); } else { // 向下兼容模式 pendingIntent = PendingIntent.getService(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); } ``` 通过这种方式可以在不同平台之间保持一致性的同时遵循最新的最佳实践指南。 --- ### 总结 上述三种解决方案分别适用于不同的开发需求和技术背景下的项目迁移过程。一般情况下优先选用第一个选项——定义成不可变更类型的 `PendingIntent` 即可消除此类问题带来的困扰。务必记得测试所有涉及通知栏消息推送以及广播发送等功能模块以验证改动效果是否符合预期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值