有没有简单的方法判断一个类是不是不可变的类?

申祷无 2020-08-31 03:20:10
不会是需要挨个看类的方法吧?
没有方法能修改对象的状态。《Java 核心技术卷I》第 10 版,146 页。另外好像字段都必须是 private 的。
https://stackoverflow.com/questions/5124012/examples-of-immutable-classes
...全文
8347 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
ljhhh7890 2020-09-07
  • 打赏
  • 举报
回复
那个贴一堆错误信息的,没有理解回答者的苦心,几行的代码还没有弄明白,就放进工程里,一大堆错误,而且只有第197行报错与此有关。
qybao 2020-09-04
  • 打赏
  • 举报
回复
引用 9 楼 街头小贩 的回复:
5楼的同学来解析一下你的代码

你改成jdk 8再试试,不要只看到新版本的变化就见怪不怪的。


引用 7 楼 申祷无 的回复:
《Java 核心编程》 146 页建议尽量使用不可变的类。我觉得你那个关于反射的观点怎么有点类似反正开锁的能开几乎所有的锁,所以谁家都不用上锁了?使用不可变的类好像可以提前让编译器把错误检测出来,不知道我记没记错,好像还有别的好处。如果有改变 private final 的属性的方法那这个类不就是可变的类了吗?我写代码测试了一下,就算某个类的属性全是 private final 的也是可以修改状态的。毕竟对于类来说 final 只是不能修改对象变量指向的对象,对象本身还是可以修改的。你的意思是 final 有类似约定的意思吗?就是说用 final 修饰就不改状态?

首先,你连什么是不可变类是怎么定义都解释不清楚,又谈何尽量使用?如果知道怎么定义,那就照着定义去判断即可。
其次,不知道【建议尽量使用不可变的类】的前提是什么?如果真是这样,为何jdk自带的类只有少量是不可变类?为啥不全都改成不可变类?
再次,你也说了final只是不让改变变量的指向,并不能控制变量指向的对象本身的属性不能修改,所以没法做到真正的“不可变”类(除非这个类的属性都是基本类型,这个类的属性指向的对象的属性也都是final或基本类型)
再次,反射只是为了告诉你本问题没什么意义,并不是说因为能开锁就不造锁。正如你所举的锁的例子,造锁也分层次的,一般层次只为防小偷,只有某些特殊领域才会用到各种生态认证(眼膜,指纹,脸部,声音等)去造高级锁。同样的,你设计一个类也是根据需求而定的,不是每个类都套用所谓的规则去把问题复杂化。也就是要学会灵活变通。
所以,你只需理解掌握什么时候该用private,什么时候该用final,就足够了,剩下所谓什么尽量不尽量的,都是private 或 final 的灵通运用而已。



街头小贩 2020-09-04
  • 打赏
  • 举报
回复
引用 13 楼 qybao 的回复:
[quote=引用 9 楼 街头小贩 的回复:] 5楼的同学来解析一下你的代码
你改成jdk 8再试试,不要只看到新版本的变化就见怪不怪的。 接受批评,向5楼大神敬礼
街头小贩 2020-09-03
  • 打赏
  • 举报
回复
引用 9 楼 街头小贩 的回复:
看到上面的回复真是无语了。Effective java和Java 语言规范有几个看了? 5楼(@qybao)的回复是通过观察变量的当前值,理解成变量前后代表的实例是同一个?jdk 11的test 5楼的同学来解析一下你的代码
jdk 11 的String value换成了byte[], 若换成
fd.set(s, "cde".getBytes());
也是可以输出cde的
街头小贩 2020-09-03
  • 打赏
  • 举报
回复
引用 10 楼 qq_39936465 的回复:
[quote=引用 8 楼 街头小贩 的回复:][quote=引用 3 楼 qq_39936465 的回复:][quote=引用 2 楼 申祷无 的回复:]final 类不是不可继承吗?
可继承类可以覆盖,重写。不可继承的类就不能被覆盖,重写。[/quote]你看到盗版书?你写一个类继承String试试[/quote] 你看清出我的答复了么?我那句说final可以被继承?[/quote] 可继承类可以覆盖,重写。不可继承的类就不能被覆盖,重写。 re: 这是你的回复吧!抱歉!
qq_39936465 2020-09-03
  • 打赏
  • 举报
回复
引用 8 楼 街头小贩 的回复:
[quote=引用 3 楼 qq_39936465 的回复:][quote=引用 2 楼 申祷无 的回复:]final 类不是不可继承吗?
可继承类可以覆盖,重写。不可继承的类就不能被覆盖,重写。[/quote]你看到盗版书?你写一个类继承String试试[/quote] 你看清出我的答复了么?我那句说final可以被继承?
街头小贩 2020-09-03
  • 打赏
  • 举报
回复
看到上面的回复真是无语了。Effective java和Java 语言规范有几个看了? 5楼(@qybao)的回复是通过观察变量的当前值,理解成变量前后代表的实例是同一个?jdk 11的test 5楼的同学来解析一下你的代码
街头小贩 2020-09-03
  • 打赏
  • 举报
回复
引用 3 楼 qq_39936465 的回复:
[quote=引用 2 楼 申祷无 的回复:]final 类不是不可继承吗?
可继承类可以覆盖,重写。不可继承的类就不能被覆盖,重写。[/quote]你看到盗版书?你写一个类继承String试试
申祷无 2020-09-03
  • 打赏
  • 举报
回复
引用 5 楼 qybao 的回复:
这道题有什么意义吗?
所谓的不可变类,对于反射来说都是可变
比如,String认为是不可变的,但是下面代码却可以改变String
public abstract class Sample {
public static void main(String[] args) {
try {
String s = "abc";
Field fd = String.class.getDeclaredField("value"); //用反射获取属性
System.out.println(fd); //可以看到value属性是private final的
fd.setAccessible(true);
fd.set(s, new char[] {'c', 'd', 'e'}); //但是通过反射还是修改了它的值
System.out.println(s); //可以看到,s引用的对象值还是变了
} catch (Exception e) {
e.printStackTrace();
}
}
}

所以你这个不可变类是有局限性的。
既然有局限性,那就判断属性是否是private final就可以了。因为通常认为属性是private就不能访问,final就不可更改,合在一起就可以认为是不可变的了。
《Java 核心编程》 146 页建议尽量使用不可变的类。我觉得你那个关于反射的观点怎么有点类似反正开锁的能开几乎所有的锁,所以谁家都不用上锁了?使用不可变的类好像可以提前让编译器把错误检测出来,不知道我记没记错,好像还有别的好处。如果有改变 private final 的属性的方法那这个类不就是可变的类了吗?我写代码测试了一下,就算某个类的属性全是 private final 的也是可以修改状态的。毕竟对于类来说 final 只是不能修改对象变量指向的对象,对象本身还是可以修改的。你的意思是 final 有类似约定的意思吗?就是说用 final 修饰就不改状态?
  • 打赏
  • 举报
回复
引用 5 楼 qybao 的回复:
这道题有什么意义吗? 所谓的不可变类,对于反射来说都是可变 比如,String认为是不可变的,但是下面代码却可以改变String
public abstract class Sample {
    public static void main(String[] args) {
        try {
            String s = "abc";
            Field fd = String.class.getDeclaredField("value"); //用反射获取属性
            System.out.println(fd); //可以看到value属性是private final的
            fd.setAccessible(true);
            fd.set(s, new char[] {'c', 'd', 'e'}); //但是通过反射还是修改了它的值
            System.out.println(s); //可以看到,s引用的对象值还是变了
        } catch (Exception e) {
            e.printStackTrace();
        }
    } 
}
所以你这个不可变类是有局限性的。 既然有局限性,那就判断属性是否是private final就可以了。因为通常认为属性是private就不能访问,final就不可更改,合在一起就可以认为是不可变的了。
反射是个好东西。可以查看属性。
qybao 2020-09-02
  • 打赏
  • 举报
回复
这道题有什么意义吗?
所谓的不可变类,对于反射来说都是可变
比如,String认为是不可变的,但是下面代码却可以改变String
public abstract class Sample {
public static void main(String[] args) {
try {
String s = "abc";
Field fd = String.class.getDeclaredField("value"); //用反射获取属性
System.out.println(fd); //可以看到value属性是private final的
fd.setAccessible(true);
fd.set(s, new char[] {'c', 'd', 'e'}); //但是通过反射还是修改了它的值
System.out.println(s); //可以看到,s引用的对象值还是变了
} catch (Exception e) {
e.printStackTrace();
}
}
}

所以你这个不可变类是有局限性的。
既然有局限性,那就判断属性是否是private final就可以了。因为通常认为属性是private就不能访问,final就不可更改,合在一起就可以认为是不可变的了。


maradona1984 2020-09-02
  • 打赏
  • 举报
回复
完全没有判断的必要,你写了不符合语法的代码编译器都不会让你通过
qq_39936465 2020-09-02
  • 打赏
  • 举报
回复
引用 2 楼 申祷无 的回复:
final 类不是不可继承吗?
可继承类可以覆盖,重写。不可继承的类就不能被覆盖,重写。
申祷无 2020-09-02
  • 打赏
  • 举报
回复
引用 1 楼 KeepSayingNo 的回复:
final类不就是不可变吗
final 类不是不可继承吗?
KeepSayingNo 2020-09-01
  • 打赏
  • 举报
回复
final类不就是不可变吗

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧