码迷,mamicode.com
首页 > 其他好文 > 详细

关于常量表达式

时间:2018-10-14 20:57:52      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:变量   常量   class   优化   www   初始   val   ssi   ret   

反射那些事反射这篇文章有谈到一个常量表达式的问题,想单独拿出来研究一下。

private final int INT_VALUE=12;//常量表达式
if(a>INT_VALUE){
    //todo
}

那么java编译器会对常量表达式进行一个优化,变成如下:

if(a>12){
    //todo
}

在知乎上看到这个观点: 把常量表达式的值求出来作为常量嵌在最终生成的代码中,这种优化叫做常量折叠(constant folding)。
原来这叫做常量折叠。
简单举个例子,上面例子没有太直观。

public class ConstantTest {

    private final int a=12; //常量表达式

    private int b=12; //普通成员变量

    private final boolean flag=null==null?true:null; //非常量表达式

    public void solve(int b){
        if(b>a){
            System.out.println("yep");
        }
    }

    public void solve(){
        if(flag){
            System.out.println(b);
        }
    }

    public static void main(String[] args) {
        ConstantTest test=new ConstantTest();
        test.solve(13);
        test.solve();
    }

}

我们对ConstantTest.class文件进行反编译看看:

package com.reflect;

import java.io.PrintStream;

public class ConstantTest {
    private final int a = 12;
    private int b = 12;
    private final boolean flag = null == null ? Boolean.valueOf(true) : null;

    public void solve(int b) {
        if (b > 12) { //这里我们看到了编译器直接进行了优化,把a直接用12来进行替代。
            System.out.println("yep");
        }
    }

    public void solve() {
        if (this.flag) { //非常量表达式和普通成员变量没有发生变化
            System.out.println(this.b);
        }
    }

    public static void main(String[] args) {
        ConstantTest test = new ConstantTest();
        test.solve(13);
        test.solve();
    }

举一些例子符合常量表达式和不符合常量表达式的例子:

public class ConstantTest {

    private final int x=2; //yes
    private final int y=x+2;//yes
    private final int f;//no 没有被初始化
    private final int z= Integer.valueOf("42");//no 不是常量表达式

    public ConstantTest() {
        this.f=2;
    }

    public static int t(){
        final int x=2;
        int y=new int[2].length;
        return x+y;
    }

    public static int s(){
        return 12*18-12+30;
    }

    public void test(){
        System.out.println(x+" "+y+" "+f+" "+z);
    }

}

反编译结果:

package com.reflect;
import java.io.PrintStream;
public class ConstantTest {
   
    private final int x = 2;
    private final int y = 4;
    private final int f = 2;
    private final int z = Integer.valueOf("42");

    public static int t() { 
        int x = 2;
        int y = new int[2].length;
        return 2 + y;
    } //向这里有人说是可以直接被优化成
    
    public static int t() { 
        return 4; //可是我的ide并没有 估计其他是可以的
    }

    public static int s() {
        return 234; //上面复杂的常量运算被优化成最终的计算结果
    }

    public void test() {
        System.out.println("2 4 " + this.f + " " + this.z);
    }

}

参考: 对于一个很复杂的常量表达式,编译器会算出结果再编译吗?
参考: Chapter 15. Expressions

关于常量表达式

标签:变量   常量   class   优化   www   初始   val   ssi   ret   

原文地址:https://www.cnblogs.com/viscu/p/9787412.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!