常量设计一:
• 常量:一种不会修改的变量
–Java没有constant关键字
–不能修改,final
–不会修改/只读/只要一份,static
–方便访问public
• Java中的常量
–public static final
–建议变量名字全大写,以连字符相连,如UPPER_BOUND
常量设计二:->简单实例China
public class China {
private final static int PEOPLE=56;//static 保证值只有一份,final保证值不会被修改
private final static String CAPITAL_CITY="Beijing";
public static void main(String[] args) {
System.out.println(China.CAPITAL_CITY);//Beijing
System.out.println(China.PEOPLE);//56个民族
}
}
常量设计三:一种特殊的常量,接口内定义的变量默认为是常量(default:public static final)
public interface Animal {
String color="unknown";//虽然没有声明为常量,但默认为public static final 的
default public void speak() {
System.out.println("Animal speak!");
}
}
class Cat implements Animal{
public void speak(){
System.out.println("喵喵喵");
}
public static void main(String[] args) {
System.out.println(Cat.color);//类直接调用
Cat.color="yellow";//编译报错
}
}
常量池一:猜一下下列程序的输出结果:
public class IntegerTest {
public static void main(String[] args) {
Integer i1=127;
Integer i2=127;
System.out.println(i1==i2);
Integer i3=128;
Integer i4=128;
System.out.println(i3==i4);
Integer i5=new Integer(127);
System.out.println(i1==i5);/
}
}
输出:
你猜对了吗?解释见下方
常量池二:
• Java为很多基本类型的包装类/字符串都建立常量池
• 常量池:相同的值只存储一份,节省内存,共享访问
• 基本类型的包装类
–Boolean,Byte,Short,Integer,Long,Character,Float,Double
–Boolean: true, false
–Byte, Character : \u0000--\u007f (0—127)
–Short, Integer, Long:-128~127 //只为-128~127这256个数建立常量池,在这个范围之外就是对象比较
–Float,Double:没有缓存(常量池) //因为浮点数小数点太多,常量池建不过来
–查看CacheTest.java
CacheTest.java
public class CacheTest {
public static void main(String[] args) {
Boolean b1=true;//范围:true/false
Boolean b2=true;
System.out.println("Boolean Test: "+String.valueOf(b1==b2));
System.out.println("----------华丽丽的分割线----------");
//java为Byte Character建立常量池的数值范围是0-127共128个数
Byte b3=127;
Byte b4=127;
System.out.println("Byte Test: "+String.valueOf(b3==b4));
Character c1=128;
Character c2=128;
System.out.println("Character Test: "+String.valueOf(c1==c2));
System.out.println("----------华丽丽的分割线----------");
//java为Short Integer Long基本类型的包装类建立常量池的数值范围是-128~127共256个数
Short s1=200;
Short s2=200;
System.out.println("Short Test: "+String.valueOf(s1==s2));
Integer i1=127;
Integer i2=127;
System.out.println("Integer Test: "+String.valueOf(i1==i2));
Long l1=-128L;
Long l2=-128L;//Long类型的数值要加上L后缀,不然会被编译器认为是int类型
System.out.println("Long Test: "+String.valueOf(l1==l2));
System.out.println("----------华丽丽的分割线----------");
//java没有为Float和Double建立常量池
Float f1=1f;
Float f2=2f;
System.out.println("Float Test: "+String.valueOf(f1==f2));
Double d1=0.5;
Double d2=0.5;
System.out.println("Double Test: "+String.valueOf(d1==d2));
}
}
输出结果:
上面结果你猜对了吗?
总结:
一:
• 基本类型的包装类和字符串有两种创建方式
–常量式(字面量)赋值创建,放在栈内存 (将被常量化)
• Integer a = 10;
• String b = “abc”;
–new对象进行创建,放在堆内存 (不会常量化)
• Integer c = new Integer(10);
• String d = new String(“abc”);
• 这两种创建方式导致创建的对象存放的位置不同
二:
• Java中的常量:static和final
• Java接口中的变量都是常量
• 对象生成有两种:常量赋值(栈内存)和new创建(堆内存)
• Java为Boolean, Byte, Character, Short, Int, Long, String 的常量
赋值建立常量池,没有包括Float和Double
• Java编译器会优化已经确定的变量
其他一些帮助理解的例子:
1. A&B.java
2. BoxClassTest.java
3. StringNewTest.java
A&B.java
public class A {
public Integer num1=100;
public Integer num2=128;
public Character c=200;
}
class B{
public Integer num1=100;
public Integer num2=128;
public Character c=200;
public static void main(String[] args) {
A a=new A();
B b=new B();
System.out.println(String.valueOf(a.num1==b.num1));//true
System.out.println(String.valueOf(a.num2==b.num2));//false Short Integer Long 类型常量池范围-128-127
System.out.println(String.valueOf(a.c==b.c));//0-127
}
}
BoxClassTest.java
public class BoxClassTest {
public static void main(String[] args) {
//1:+ 操作使对象拆箱
//2:基本类型与基本类型的包装类比较,包装类拆箱,二者比较数值大小
//3:两个包装类对象比较,比较地址。这里要注意常量池所在的栈地址以及new产生的堆地址
int i1=10;
Integer i2=10;
System.out.println(i1==i2);
Integer i3=new Integer(10);
System.out.println(i1==i3);
System.out.println(i2==i3);
System.out.println("------------------");
Integer i4=new Integer(4);
Integer i5=new Integer(6);
System.out.println(i1==(i4+i5));// true i4+i5 加法操作 ->使右边拆箱-> 两边都是基本类型
System.out.println(i2==(i4+i5));//true 右边拆完左边拆 最后两个基本类型比较
System.out.println(i3==(i4+i5));// true 右边拆完左边拆 最后两个基本类型比较
System.out.println("------------------");
Integer i6=i4+i5;
System.out.println(i1==i6);
System.out.println(i2==i6);
System.out.println(i3==i6);
}
}
运行结果:
你猜对了吗?
StringNewTest.java
public class StringNewTest {
public static void main(String[] args) {
String s0="abcdef";
String s1="abc";
String s2="abc";
String s3=new String("abc");
String s4=new String("abc");
System.out.println(s1==s2);
System.out.println(s1==s3);//false 一个栈内存,一个堆内存
System.out.println(s3==s4);//false 分别指向堆内存中两块不同的空间
System.out.println("----------------------");
String s5=s1+"def";//涉及到变量编译器不优化 s1为一个String类型的变量
String s6="abc"+"def";//都是常量,优化
String s7="abc"+new String("def");//涉及到new对象,编译器不优化
System.out.println(s5==s6);
System.out.println(s0==s6);
System.out.println(s6==s7);
System.out.println(s5==s7);
System.out.println("----------------------");
String s8=s3+"def";
String s9=s3+"def";
String s10=s3+new String("def");
System.out.println(s8==s9);
System.out.println(s8==s10);
System.out.println(s9==s10);
}
}
输出结果:
------------------------END------------------------
注:
参考内容:华东师范大学 陈良育教授 中国大学mooc java核心技术基础
转载需注明出处