一、自增变量
public class Main {
public static void main(String[] args) {
//i++是先把i压入栈,后对局部变量进行自增,++i是先对局部变量进行自增,后压入栈
int i = 1;//局部变量为1
i = i++;//先把1压入栈,局部变量i的值目前为1,自增以后,局部变量i的值变为2,赋值以后又变为1,所以这一步结果为1
int j = i++;//这一步和上一步雷同,i先压栈,后自增i变为2,再将栈中的1赋值给j变量
int k = i + ++i * i++;//将上一步i的结果2压栈,++i先把局部变量i的值变为3再压入栈中,i++是先将3压入栈中,再对局部变量i进行自增操作变为4,栈中得到结果为11
System.out.println(i);//4
System.out.println(j);//1
System.out.println(k);//11
}
}
小结:赋值最后计算,=右边的从左至右依次压入操作数栈,自增自减都是直接修改局部变量的值,不经过操作数栈,最后的赋值之前,临时结果也是存储在操作数栈中(i++就是先压栈后自增,++i就是先自增后压栈)
二、单例设计模式(编写一个Singleton示例)
要点:
- 某个类只能有一个实例:构造器私有化
- 必须自行创建这个实例:含有一个该类的静态变量来保存这个唯一的实例
- 必须自行向整个系统提供这个实例:(1)直接暴露 (2)用静态变量的get方法获取
几种常见形式:
1、饿汉式:直接创建对象,不存在线程安全问题
1)直接实例化饿汉式(简洁直观):在类初始化时直接创建实例对象,不管你是否需要这个实例对象,对象都会创建
public class Singleton1 {
public static final Singleton1 INSTANCE = new Singleton1();
private Singleton1() {
}
}
2)枚举
JDK1.5引入了新的类型——枚举。在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便。
在JDK1.5 之前,我们定义常量都是: public static fianl....(这种方式在现在项目中也很常见) 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。而且枚举类型可以帮助我们检测许多的编译失误。
在类加载的时候就初始化静态变量,默认调用私有构造方法去创建对象。
/*
* 枚举类型,表示该类型的对象是有限的几个
* 我们可以限定为一个,就成了单例
*/
public enum Singleton2 {
INSTANCE; //相当于public static final Singleton2 INSTANCE = new Singleton2();创建了一个静态常量,并在类初始化的时候去调用无参构造
private Singleton2(){} //默认调用这个私有的无参构造函数
}
3)静态代码块饿汉式(适合复杂实例化)
思考:如果把throw new RuntimeException(e) 这一行注释掉,则静态变量会显示未被初始化,但是加上这句话则可以,这是为什么呢?
个人理解:当时我就在想,如果常量一开始不赋初值的话,那么可以在静态代码块里赋值,而且如果把赋值语句写在try语句块外面,则不会报错,因为写在try语句块里面,编译器会认为走不到里面,所以会报错,但是如果你把可能出现的异常捕获并抛出,则编译器会认为try语句块不会出现异常,所以加上这句话即可实例化
public class Singleton3 {
public static final Singleton3 INSTANCE;
private String info;
static {
try {
Properties pro = new Properties();
pro.load(Singleton3.class.getClassLoader().getResourceAsStream("single.properties"));
INSTANCE = new Singleton3(pro.getProperty("info"));
} catch (IOException e) {
// e.printStackTrace();
throw new RuntimeException(e);
}
}
private Singleton3(String info){
this.info = info;
}
public static Singleton3 getINSTANCE() {
return INSTANCE;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {