类变量和类方法
1.类变量(静态变量)用static 修饰,所有对象共享 【jdk7之前存在于方法区,之后存在于堆】实例变量则是每个对象独享
2.类变量使用方法为:类名.类变量\对象名.类变量【推荐使用前者】 实例变量不能通过类名.类变量名访问
3.类变量在类加载时初始化,不需创建对象就可以使用,生命周期随类加载开始,随类消失而销毁。【类方法前三点同样符合】
4.如果想要在类内方法访问类变量,则必须用static修饰方法,使其成为类方法。
5.类方法中不允许使用this和super关键字【因为this代表的是调用这个函数的对象的引用,而静态方法是属于类的,不属于对象,静态方法成功加载后,对象还不一定存在, 同样super代表对父类对象的引用,指向父类对象 | this和super是属于对象范畴的东西,而静态方法是属于类范畴的东西】
6.类方法只能访问类变量或其他静态方法,普通成员方法可以访问类变量,类方法,普通成员变量。
继承关系中的类成员:
1.不仅类的实例对象共享类的静态变量,父类的所有子类和子类对象也都共享父类的静态变量,有且仅有一份,对其进行修改,会影响到所有类及对象;
2.因为静态方法从程序开始运行后就已经分配了内存,也就是说已经写死了。所有引用到该方法的对象(父类的对象也好子类的对象也好)所指向的都是同一块内存中的数据,也就是该静态方法。子类中如果定义了相同名称的静态方法,并不会重写,而应该是在内存中又分配了一块给子类的静态方法,没有重写这一说,我们应该称之为隐藏
小结:
子类是不继承父类的static变量和方法的。因为这是属于类本身的。但是子类是可以访问的。
子类和父类中同名的static变量和方法都是相互独立的,并不存在任何的重写的关系
深入理解main方法:public static void main(String[] args)
代码块
创建对象时先运行静态代码块(随着类的加载被执行),其次匿名(普通)代码块,之后运行构造方法,多次创建对象时静态代码块仅在第一次执行,普通代码块每次创建对象都会执行。代码块的修饰符只有static,有或没有分为两种。
在构造函数执行前一定会先调用super 和 本类的普通成员和普通代码块
类什么时候被加载?
①创建对象实例时(new)
②创建子类对象实例,父类也会被加载,同时父类先被加载,子类后被加载
③使用类的静态成员(静态方法,静态属性),在仅仅使用类静态成员的情况下普通代码块不会被执行。
输出:第一条语句:In static block! 100 第二条语句 100; 按图中1234顺序输出。
单例模式
饿汉式:1.将构造函数私有化 2. 在类的内部直接创建对象(该对象用static修饰) 3. 提供一个public 的static方法,来返回创建的对象
public class sig_instance { public static void main(String[] args) { girlfriend gf = girlfriend.Instance(); System.out.println(gf); girlfriend gf1 = girlfriend.Instance(); System.out.println(gf1); } } class girlfriend{ private String name; private static girlfriend gf = new girlfriend("小红"); private girlfriend(String name) { this.name = name; } public static girlfriend Instance(){ return gf; } }懒汉式:为了防止饿汉式中,当调用了其他类成员会顺便在类内new一个对象导致浪费资源(因为都是static修饰)的问题。所以设置当用户调用了Instance才会创建对象
public class sig_instance { public static void main(String[] args) { System.out.println(girlfriend.age); girlfriend gf = girlfriend.Instance(); System.out.println(gf); } } class girlfriend{ private String name; static int age = 18; private static girlfriend gf; private girlfriend(String name) { this.name = name; System.out.println("ahah"); } public static girlfriend Instance(){ if(gf == null){ gf = new girlfriend("haha"); } return gf; } @Override public String toString() { return "girlfriend{" + "name='" + name + '\'' + '}'; } }
贴士: