Java教程

Java中的常量优化机制

本文主要是介绍Java中的常量优化机制,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

问题抛出:静态常量(static final)可以再编译器确定字面量,但常量(final或者String a = “a”或者Integer的 -128-127)并不一定在编译期就确定了, 也可以在运行时确定.所以Java针对某些情况制定了常量优化机制。

拓展:

为啥Integer是-128-12

如果对assert感兴趣可以查看:https://www.cnblogs.com/jpfss/p/10973837.html

常量优化机制:给一个变量赋值,如果等于号的右边是常量的表达式并且没有一个变量,那么就会在编译阶段计算该表达式的结果,然后判断该表达式的结果是否在左边类型所表示范围内,如果在,那么就赋值成功,如果不在,那么就赋值失败。但是注意如果一旦有变量参与表达式,那么就不会有编译期间的常量优化机制

结合问题,我们就可以大致猜出,如果常量能在编译期确定就会有优化,不能的话就不存在。

下面我们来详细讲解一下这个机制,Java中的常量池常量优化机制主要是两方面

byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。

short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。

int:32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。

long:64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。

float:32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。

double:64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。

boolean:只有true和false两个取值。

char:16位,存储Unicode码,用单引号赋值。

Java决定了每种简单类型的大小。这些大小并不随着机器结构的变化而变化。这种大小的不可更改正是Java程序具有很强移植能力的原因之一。下表列出了Java中定义的简单类型、占用二进制位数及对应的封装器类。

一、就是对于byte/short/char三种类型的常量优化机制

1.以下面这个程序为例

   byte b1  = 1 + 2;
   System.out.println(b1);
   // 输出结果 3

运行结果解释:1和2都是常量,Java有常量优化机制,就是可以编译时可以明显确定常量结果,所以直接把1和2的结果赋值给b1了。(和直接赋值3是一个意思)

2.换一种情况看看,把右边常量改成变量

      byte b1  = 3;
      byte b2  = 4;
      byte b3 = b1 + b2;
      System.out.println(b3);  // 程序报错

 

程序报错了,意思说类型不匹配:无法从int转换为byte

 

解释原因,从两个方面:

  1. byte 与 byte (或者 short char ) 进行运算的时候会提升int 两个int 类型相加的结果也是int 类型
  2. b1 和 b2 是两个变量,变量存储的是变化 ,在编译的时候无法判断里面的值,相加有可能会超出byte的取值

这就是为什么一旦有变量参与表达式,那么就不会有编译期间的常量优化机制

3.在这里我们试着把变量添加final改回常量,看看又有什么结果 

    final byte b1  = 1;
    final byte b2  = 2;
    byte b3 = b1 + b2;
    System.out.println(b3);//3

输出的结果是3,因为b1和b2都是final修饰的,所以是常量,所以b3的时候就是常量相加不会出现编译的问题。

4、接下来我们再看另外一个程序

byte b1  = 127 + 2;   
System.out.println(b4);

 

会出现编译报错,因为是常量在做相加,而且byte的取值范围是-128~127,很明显右边表达式的结果是不在左边类型所表示范围,这个就是导致此错误出现的原因。

 

 5.某些场景下,取值范围大的数据类型(int)可以直接赋值给取值范围小的(byte、short、char),而且只能特定int赋值给byte/short/char,其他基本数据类型不行,如下图。

int num1 = 10;
final int num2 = 10;
byte var1 = num1 + 20;  // 存在变量,编译报错
byte var2 = num2 + 20; // 编译通过

所以我们这里总结一下byte/short/char三种类型的常量优化机制

  1. 先判断值是否是常量, 然后再看值是否在该数据类型的取值范围内
  2. 只有byte, short, char 可以使用常量优化机制,转换成int类型(这个你换成其他基本数据类型就不适应了)
//额外例子说明
char d = 65;
char a = 11;
System.out.println(d);//打印是A
System.out.println(a);//打印是空的

为啥a打印的是空,d打印是A,因为a打印的时候在ASCII等字符编码表中有对应的数值

char类型是可以运算的因为char在ASCII等字符编码表中有对应的数值

拓展一下(易错点):

byte var = 10;
var = var + 20; // 编译报错,运算中存在变量
var += 20; // 等效于: var = (short) (var + 20); 没有走常量优化机制,而是进行了类型转换

 

这篇关于Java中的常量优化机制的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!