V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gramyang
V2EX  ›  Java

为什么 Java 的类型引用全都是指针传递呢?

  •  
  •   gramyang · 2019-08-24 16:56:53 +08:00 · 6367 次点击
    这是一个创建于 1946 天前的主题,其中的信息可能已经有所发展或是发生改变。

    以前不觉得,现在发现这种设计真的是有毒。

    java 原生的深拷贝方法麻烦无比,用 gson 来做深拷贝简单点,但是为了避免栈溢出,一些存在相互引用可能的类型需要加上 transient,并且在深拷贝后再把 transient 变量赋值进去。

    其实像 go 那样使用肥指针就不会有这么多幺蛾子了。。

    22 条回复    2019-08-27 12:59:13 +08:00
    weixiangzhe
        1
    weixiangzhe  
       2019-08-24 17:07:42 +08:00 via iPhone
    貌似大部分对象都是引用赋值了吧 rust 的借用是不是可以满足楼主
    reus
        2
    reus  
       2019-08-24 17:14:07 +08:00
    说要加 value types 好几年了
    chendy
        3
    chendy  
       2019-08-24 17:16:32 +08:00   ❤️ 3
    其实是 值传递,传递了引用的值…
    soulzz
        4
    soulzz  
       2019-08-24 17:16:56 +08:00
    主要是省空间,赋新值就开辟个新空间有些浪费
    但问题也很蛋疼,每次我解决深拷贝的问题都是序列化再反序列化感觉更浪费资源了
    zifangsky
        5
    zifangsky  
       2019-08-24 17:27:12 +08:00
    3L 说得对
    gramyang
        6
    gramyang  
    OP
       2019-08-24 17:27:21 +08:00
    @soulzz 我感觉这个不是省空间,而是 java 的开发者纯粹想屏蔽指针,这种想法已经过时了
    Yuicon
        7
    Yuicon  
       2019-08-24 18:20:01 +08:00
    @gramyang 95 年的 java 你用现在的眼光来看当然过时了
    pursuer
        8
    pursuer  
       2019-08-24 19:16:27 +08:00
    大概因为引用传递适合大部分的情况,所以就默认使用引用传递。值拷贝在处理复杂对象时不一定把一块内存复制过去就可以了,所以 c++为了处理这个情况还搞了个复制构造函数,Java 中对应的就是 clone 方法,只是 Java 默认是引用传递,c++默认是值传递
    gramyang
        9
    gramyang  
    OP
       2019-08-24 19:43:56 +08:00
    @chendy 我知道,网上很多答案都这么说,原理也确实是如此。所有的代码的行为几乎都是值传递,取值和赋值,指针也是值传递,但是我觉得还是有必要把复制指针和复制指针指向的值区别开来
    danc
        10
    danc  
       2019-08-24 20:46:41 +08:00
    所以,rust 应该能满足大佬的需求,想要传引用就&T, 想要拷贝就 T.clone()
    bumz
        11
    bumz  
       2019-08-24 21:00:03 +08:00 via iPhone
    @gramyang

    Java 只不过没指针运算罢了
    还是指针

    现代语言基本都淘汰指针运算了,比如 go 改用 slice 就很先进
    EmdeBoas
        12
    EmdeBoas  
       2019-08-24 21:10:14 +08:00
    <dependency>
    <groupId>uk.com.robust-it</groupId>
    <artifactId>cloning</artifactId>
    </dependency>
    laminux29
        13
    laminux29  
       2019-08-24 21:29:26 +08:00
    C/C++中的:
    *p
    **p
    ***p
    p + (b + (a*n) )

    题主,以上你都能快速理解吗?你猜猜考试中,全能理解的有多少?
    middleware
        14
    middleware  
       2019-08-25 00:28:01 +08:00
    Value type 的 life cycle 不能统一由 GC 控制,语法必然复杂化。
    Raymon111111
        15
    Raymon111111  
       2019-08-25 00:36:35 +08:00
    BeanUtils.copyProperties
    wysnylc
        16
    wysnylc  
       2019-08-25 02:12:44 +08:00
    为了解决一个问题带出来更多问题
    Takamine
        17
    Takamine  
       2019-08-25 09:13:59 +08:00 via Android
    看到标题的时候我觉得是个伪命题阿。
    话说想到之前一个问题,Java 到底是只有值传递还是也有引用传递:doge:。
    Sasasu
        18
    Sasasu  
       2019-08-25 13:58:22 +08:00 via Android
    没理解 go 里的胖指针是什么
    指 interface 的话,胖指针让编译器失去了很多优化的机会,让 go 程序员不得不手动检查的函数的逃逸分析,编译器升级后还要再检查一遍。
    指带长度的 slice 的话 Java 里也有 object[],而且还不会 cow
    watzds
        19
    watzds  
       2019-08-25 14:29:05 +08:00 via Android
    C++里不也喜欢传指针,Java 这样简单
    cyspy
        20
    cyspy  
       2019-08-25 14:39:19 +08:00
    首先是因为 Java 除了八种基本类型之外都在堆里分配,有点原教旨的面向对象了,更现代的语言一般都把小 struct 分配在栈上
    Aresxue
        21
    Aresxue  
       2019-08-26 15:21:29 +08:00
    两个原因,快还有"懒"。快是指针存在虚拟机栈里,copy 起来速度奇快,"懒"是 JVM 的实现人员觉得没必要为 1%的场景去花费太多精力,有那空不如研究研究垃圾收集器啥的。。。不过听说新版本好像有这个意向?
    shm7
        22
    shm7  
       2019-08-27 12:59:13 +08:00
    因为快吧。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2493 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 05:25 · PVG 13:25 · LAX 21:25 · JFK 00:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.