目录
静态变量与成员变量的区别
1、两个变量的生命周期不同 成员变量随着对象的创建而存在,随着对象被回收而释放。 静态变量随着类的加载而存在,随着类的消失而消失。 2、调用方式不同 成员变量只能被对象调用。 静态变量可以被对象调用,还可以被类名调用。 3、别名不同 成员变量也称为实例变量,成员变量-对象的特有属性 静态变量也称为类变量,静态变量-对象的共有属性 类成员 4、数据存储位置不同 成员变量存储在堆内存的对象中,所以也叫对象的特有数据。 静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。
举个例子:
public class Test {
public static void main(String[] args) {
A a=new A();
System.out.println(a==a.a);
System.out.println(a.a==a.a.a);
}
}
class A{
A a=new A();
}
编译不报错,但是运行报错:
这是“栈溢出”的错误,原因是构造函数一直在进栈
public class Test {
public static void main(String[] args) {
// A a=new A();
// System.out.println(a==a.a);
// System.out.println(a==a.a.a);
B b=new B();
System.out.println(b==b.b);//false
System.out.println(b.b==b.b.b);//true
}
}
class B{
static B b=new B();
}
class A{
A a=new A();
}
没有报错,结果是:
解析:
b中没有成员变量,只有静态变量。主函数进栈,创建b,将0x456给b。
b.b是通过对象调用成员,先去堆中的对象空间找,没有找到,再去静态区找,找到了,为0x123;那么结果就是false。
b.b.b是0x123,b.b.b先去这个对象当前的所属空间里面去找成员变量b,没有找到,再去静态区找,找到了b,是它本身。结果就是true。
所以b.b.b==b.b.b.b.b.b.b.b.b.b.b,结果也是true。
代码块
代码块 { ... }就是一对{},里面有代码
- 局部代码块:存在于函数当中(包括函数) for(){...} if () {...}
- 构造代码块:直接在类中出现的{...} 当对象创建一次,构造代码块执行一次。作用等同于构造函数。
- 静态代码块:直接在类中出现的static{...} 当类被加载的时候,仅且只执行一次。作用于对类进行一些初始化操作 JDBC
class CodeBlock{
{
System.out.println("构造代码块");
}
static{
System.out.println("静态代码块");
}
public static void main(String[] args){
CodeBlock c1=new CodeBlock();
CodeBlock c2=new CodeBlock();
CodeBlock c3=new CodeBlock();
}
}
结果:
静态代码块
构造代码块
构造代码块
构造代码块
单例模式
设计模式:就是我们的前辈们总结出来的一些编码技巧,它并不是随着Java的诞生而诞生的,它是由Java的广大使用者总结出来的一套编码经验,常见有26种。
比如某一个朝代的皇帝 只能是唯一的
1.既然只能创建一个对象的话,就得不能让外界去创建对象。限制使用new不现实,只能从对象的创建流程中考虑 只要有一个步骤不行,对象就创建不出来。开辟空间分配地址,是由计算机底层决定,我们也控制不了。构造函数执行,只需要将构造函数私有化即可。
class SingleTest{
public static void main(String[] args){
Single s1=Single.getInstance();
Single s2=Single.getInstance();
//s2=null;
Single s3=Single.getInstance();
System.out.println(s1==s2);
System.out.println(s2==s3);
}
}
2.既然外界不能创建对象,我们还得保证对象的创建,所以我们只能在类内部创建对象 Single s=new Single();
但不能写成成员变量的形式,因为成员变量存在的前提是创建对象,但是外界创建不了对象,无法将成员变量向外提供。所以private static
3.内部创建出对象,还得向外界提供。因为private,外界不能直接访问。所以间接访问,向外界提供一个函数,外界通过调用函数获取对象。
//饿汉式 比较急 所以直接返回对象
/*
class Single{
private static Single s=new Single();
private Single(){}
public static Single getInstance(){
return s;
}
}
*/
//饱汗式 比交满 不急 判断一下
class Single{
private static Single s;
private Single(){}
public static Single getInstance(){
if(s==null){
s=new Single();
}
return s;
}
}
结果:
true
true
如果s2=null,对s3没有影响。