static
Java中的static关键字(可作用在)
–变量
–方法
–类
–匿名方法块
首先,我们来看静态变量;
静态变量,类共有成员
–static变量只依赖于类存在(通过类即可访问),不依
赖于对象实例存在。所以可以通过类直接访问static变量;
public class Potato {
static int price = 5;
String content = "";
public Potato(int price, String content)
{
this.price = price;
this.content = content;
}
public static void main(String[] a)
{
System.out.println(Potato.price);
}
}
所有的对象实例,如例子中的obj1和obj2关于price变量
的值都共享存储在一个共同的空间(栈)
public class Potato {
static int price = 5;
String content = "";
public Potato(int price, String content)
{
this.price = price;
this.content = content;
}
public static void main(String[] a)
{
System.out.println(Potato.price); //Potato.content wrong
System.out.println("----------------------------------");
Potato obj1 = new Potato(10,"青椒土豆丝");
System.out.println(Potato.price);
System.out.println(obj1.price);
System.out.println("----------------------------------");
Potato obj2 = new Potato(20,"酸辣土豆丝");
System.out.println(Potato.price);
System.out.println(obj2.price);
System.out.println(obj1.price==obj2.price);
}
}
static块 –只在类第一次被加载时调用。
–换句话说,在程序运行期间,这段代码只运行一次。
–执行顺序:static块 > 匿名块 > 构造函数。
final
Java的final关键字同样可以用来修饰
–类
–方法
–字段
final的类,不能被继承;
final的方法不能被改写,即不能修改方法,可以改变参数;
final的字段不能被修改值,值都是固定的;
final的对象不能变更指针。
class FinalObject
{
int a = 10;
}
public class FinalObjectTest {
public static void main(String[] args) {
final FinalObject obj1 = new FinalObject();
System.out.println(obj1.a);
obj1.a = 20;
System.out.println(obj1.a);
obj1 = new FinalObject();
//final对象不能变更指针
}
}
public class FinalPrimitiveType {
public static void main(String[] args) {
// TODO Auto-generated method stub
final int a = 5;
a=10;//final的基本类型不能修改值
}
}
常量设计
Java中的常量
–public static final
–建议变量名字全大写,以连字符相连,
public class Constants {
public final static double PI_NUMBER = 3.14;
public static final String DEFAULT_COUNTRY="China";
public static void main(String[] a)
{
System.out.println(Constants.PI_NUMBER);
System.out.println(Constants.DEFAULT_COUNTRY);
}
}
常量池
Java为很多基本类型的包装类/字符串都建立常量池
• 常量池:相同的值只存储一份,节省内存,共享访问
• 基本类型的包装类
–Boolean,Byte,Short,Integer,Long,Character,Float,Double
–Boolean: true, false
–Byte, Character : \u0000–\u007f (0—127)
–Short, Int, Long:-128~127
–Float,Double:没有缓存(常量池)
常量式(字面量)赋值创建,放在栈内存 (将被常量化)
• Integer a = 10;
• String b = “abc”;
–new对象进行创建,放在堆内存 (不会常量化)
• Integer c = new Integer(10);
• String d = new String(“abc”);
• 这两种创建方式导致创建的对象存放的位置不同
public static void main(String[] args) {
Integer n1 = 127;
Integer n2 = 127;
System.out.println(n1==n2); //true
//对象双等号是比较指针是否指向同一个东西
Integer n3 = 128;
Integer n4 = 128;
System.out.println(n3==n4);//false
Integer n5 = new Integer(127);
System.out.println(n1==n5);//false
}
分析String类
–常量赋值(堆内存)和new创建(栈内存)不是同一个对象
–编译器只会优化确定的字符串,并缓存
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); //true 常量池
System.out.println(s1 == s3); //false 一个栈内存,一个堆内存
System.out.println(s3 == s4); //false 两个都是堆内存
System.out.println("=========================");
String s5 = s1 + "def"; //涉及到变量,故编译器不优化
String s6 = "abc" + "def"; //都是常量 编译器会自动优化成abcdef
String s7 = "abc" + new String ("def");//涉及到new对象,编译器不优化
System.out.println(s5 == s6); //false
System.out.println(s5 == s7); //false
System.out.println(s6 == s7); //false
System.out.println(s0 == s6); //true
System.out.println("=========================");
String s8 = s3 + "def";//涉及到new对象,编译器不优化
String s9 = s4 + "def";//涉及到new对象,编译器不优化
String s10 = s3 + new String("def");//涉及到new对象,编译器不优化
System.out.println(s8 == s9); //false
System.out.println(s8 == s10); //false
System.out.println(s9 == s10); //false
基本类型和包装类比较,将对包装类自动拆箱
int i1 = 10;
Integer i2 = 10; // 自动装箱
System.out.println(i1 == i2); //true
// 自动拆箱 基本类型和包装类进行比较,包装类自动拆箱
Integer i3 = new Integer(10);
System.out.println(i1 == i3); //true
// 自动拆箱 基本类型和包装类进行比较,包装类自动拆箱
System.out.println(i2 == i3); //false
// 两个对象比较,比较其地址。
// i2是常量,放在栈内存常量池中,i3是new出对象,放在堆内存中
Integer i4 = new Integer(5);
Integer i5 = new Integer(5);
System.out.println(i1 == (i4+i5)); //true
System.out.println(i2 == (i4+i5)); //true
System.out.println(i3 == (i4+i5)); //true
// i4+i5 操作将会使得i4,i5自动拆箱为基本类型并运算得到10.
// 基础类型10和对象比较, 将会使对象自动拆箱,做基本类型比较
对象比较,比较地址
加法,自动拆箱