jdk源码中为什么把成员变量赋值给局部变量再操作

https://segmentfault.com/q/1010000040896700

问题

在对象的方法中使用对象的成员变量时,为什么喜欢先把它赋值给这个方法的局部变量?为了不可变性吗?

先上代码:

public class SomeObject{
    private Subscription subscription;
    public void foo(long n){
        Subscription s = this.subscription;
        s.request(n);
    }
}

反正自己平时写代码时,在foo(n)中就直接掉用this.subscription.request(n)了。但其实仔细想想,好像很多比较规范的源码中都会先把成员变量赋值给一个方法的局部变量,再操作这个局部变量。

我个人的第一感觉是:是不是防止在代码中出现类似下面的代码,进而造成改变了成员变量的实时。即:从类的不变性角度触发才像上面这样写:

public void foo(long n){
    //写代码、或修改代码时,在这个方法中需要换一个subscription对象
    if(
        this.subscription.request(n)
            .notSatisfySomeCondition()
    ){
        this.subscription = new AnotherSubscriptionImpl();
        this.subscription.request(n);
    }
}

个人感觉自己这样理解没问题,有谁能给个准话吗?
类似的代码还有很多,我挑几个立即就能想到的:

//reactor-core的BaseSubscriber.java
    @Override
    public final void request(long n) {
        if (Operators.validate(n)) {
            Subscription s = this.subscription;
            if (s != null) {
                s.request(n);
            }
        }
    }
//HashMap的随便一个方法,如putVal(...)
 final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        //这里的tab = this.table   源码是tab=table,这里为了突出效果而加了this.
        if ((tab = this.table) == null || (n = tab.length) == 0)
        //...process with tab but not table
 }

补充:这里不是要讨论不可变类的实现,因为它的内容比较多。

回答

在这里插入图片描述

你可以看下我上图的例子,对比一下左侧代码23行和25,以及右侧生成的字节码。你会发现获取b和c只需要调用iload,从本地方法栈取值,但是获取a的时候,aload->获取this,getfield->获取a的值,需要两步操作。

如果代码里都是使用成员变量,那么底层字节码每次都要先获取this,再getfield.而赋值给局部变量后就直接load局部变量就好了.

把成员变量赋值给局部变量是为了抠性能,对于底层还是有必要的,
对于业务层就比较无所谓了

参考

http://www.blogjava.net/java-blog/articles/158871.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值