一、static
“静态”
可用的地方
变量、方法、类、匿名方法块
特点
1.静态变量
只依赖类存在不依赖对象实例存在,可以用类名直接调用即无论有多少个实例对象,他们共享的是同一个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)
{
//1.可以用类名直接调用静态变量
System.out.println(Potato.price);
System.out.println("----------------------------------");
//2.实例化了两个对象但是用的是同一个静态变量price
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);
}
}
2.静态方法
可以用类名直接调用,不依赖对象,但是静态方法中不能调用任何非静态的元素(比如说非静态变量、非静态方法)。可以含有非静态的变量但是不能调用。
public class StaticMethodTest {
int a = 111111;
static int b = 222222;//静态变量
//静态方法
public static void hello()
{
System.out.println("000000");
System.out.println(b);
//System.out.println(a); //error, cannot call non-static variables
//hi() //error, cannot call non-static method
}
//非静态方法
public void hi()
{
System.out.println("333333");
hello(); //ok, call static methods
System.out.println(a); //ok, call non-static variables
System.out.println(b); //ok, call static variables
}
public static void main(String[] a)
{
StaticMethodTest.hello();
//StaticMethodTest.hi(); //error, 不能使用类名来引用非静态方法
StaticMethodTest foo = new StaticMethodTest();
foo.hello(); //warning, but it is ok
foo.hi(); //right
}
}
3.静态类
一般修饰的是内部类,不常见就此略过。
4.静态代码块
没有名字的方法,在new这个类时调用顺序:静态static块>匿名块>构造函数。
class StaticBlock
{
//staticl block > anonymous block > constructor function
//静态static块
static
{
System.out.println("22222222222222222222");
}
//匿名块
{
System.out.println("11111111111111111111");
}
//构造函数
public StaticBlock()
{
System.out.println("33333333333333333333");
}
//匿名块
{
System.out.println("44444444444444444444");
}
}
二、单例模式
由static变量在众多实例中只有一个拷贝的性质延伸出设计模式中的–单例模式(单态模式)。顾名思义就是规定一个类只能生成一个对象(只能new一次),内存空间中只能有一个对象。
单例模式属于创建型,那么如何创建一个单例模式呢
采用static来共享对象实例,用private构造函数,防止外界new。
public class Singleton {
private static Singleton obj = new Singleton(); //共享同一个对象
private String content;
private Singleton() //确保只能在类内部调用构造函数
{
this.content = "abc";
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public static Singleton getInstance() {
//静态方法使用静态变量
//另外可以使用方法内的临时变量,但是不能引用非静态的成员变量
return obj;
}
public static void main(String[] args) {
//会发现就算时new了两次但生成的obj1和obj2是同一个对象
Singleton obj1 = Singleton.getInstance();
System.out.println(obj1.getContent()); //abc
Singleton obj2 = Singleton.getInstance();
System.out.println(obj2.getContent()); //abc
obj2.setContent("def");
System.out.println(obj1.getContent());
System.out.println(obj2.getContent());
System.out.println(obj1 == obj2); //true, obj1和obj2指向同一个对象
}
}
三、final
定义后不可修改
可用的地方:
类、方法、变量
特点
final类不能被继承
final方法不能被重写
final变量不能被更改
四、常量设计和常量池
常量:不会修改的变量
怎么满足条件呢
不能修改final
不会修改/只能是一份static
方便访问public
---->public static final
static保证只有一份,final保证不会被修改
常量池
为了提高性能,节省内存的目的,Java提出了常量池的概念即
常量池:相同的值只存一份,节省内存,共享访问
有常量池的分别是基本类型、基础类型的包装类和常量字符串。
“双等号”比较的是对象的地址,也就是是否是同一个对象;equal比较的是对象的值。
1.基本类型
自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。
int 变为Integer 时 如果值在-128~127之间 则不会创建新的integer对象 储存常量池中,这么做的目的是提高效率。
2.基础类型的包装类:
public static void main(String[] args) {
Integer n1=127;
Integer n2=127;
Integer n3=128;
Integer n4=128;
System.out.println(n1==n2);//true
System.out.println(n3==n4);//false
}
3.常量字符串
public static void main(String[] args) {
String s="abc";
String d="a"+"b"+"c";
System.out.println(s==d);//true
String a="xxx";
String b="xxx";
System.out.println(a==b);//true
}
- 栈内存读取速度快,但容量小。堆内存读取速度慢,但容量大
- 包装类生成的是一个对象,会先装箱成一个对象于基本类型比较的时候会自动拆箱