01-类变量和类方法
02-main方法
03-代码块
04-单例设计模式
01-类变量和类方法
一、类变量
基本概念: 类变量也称静态变量/静态属性,是类的所有对象共享的变量,对象去访问它时,取到的值是相同的,同样任何一个该类对象去修改的也是同一个变量。
定义语法: 访问修饰符 static 数据类型 变量名;(访问修饰符和static可调换)
基本使用: 类名.变量名(推荐) 对象名.变量名
public class Test{
public static void main(String[] args) {
System.out.print(AA.number)0 // 100 类名调用
System.out.print((new AA()).number) // 100 对象调用
}
}
class AA {
public static int number = 100; // 定义
}
注意细节:
1.当我需要某个类的所有对象都共享一个变量的时,就可以考虑使用静态变量。
2.类变量是该类所有对象共享的,而实例变量是每个对象独享的。
3.加上static成为类变量或静态变量,否则就是实例变量/普通变量/非静态变量。
4.实例变量不能通过 对象名.变量名来访问。
5.类变量是类加载时就初始化了,也就说,即使你没有创建对象,只要类加
载了,就可以使用类变量,不需要创建对象,就可以使用。
6.类变量的生命周期时随类的加载开始,随类的消亡而消亡。
二、类方法
基本概念: 类方法就是静态方法。
定义语法: 访问修饰符 static 数据返回类型 方法名(){}; (推荐使用)
static 访问修饰符 数据返回类型 方法名(){};
基本使用: 对象名.类方法 类名.类方法 (推荐)
public class Test{
public static void main(String[] args) {
System.out.print(AA.eat()); // 我每天都要吃饭~ 类名调用
System.out.print((new AA()).eat()); // 我每天都要吃饭~ 对象调用
}
}
class AA {
public static void eat(){
System.out.print("我每天都要吃饭~");
}
}
使用场景:
1.当放方法不涉及任何对象相关的成员,则可以将方法设计乘静态方法,提高效率。
2.在开发阶段,往往会将一些通用的方法,设计成静态方法,可以通过类名直接调用。
注意细节:
1.类方法和普通方法都是随着类加载而加载,将结构信息储在方法区。
2.类方法中无this的参数,普通方法隐含this参数。
3.普通方法和对象有关,只能通过对象名调用,不能通过类方法调用。
02-main方法
深入了解main方法
public class Test{
public static void main(String[] args) {
}
}
1.java虚拟机需要调用类的main方法,所以可该方法的访问限权必须时public。
2.java虚拟机执行main方法的时候不需要创建对象,所以该方法必须static。
3.该方法接收String类型的数组参数,该数组中保存java命令时所传递的参数
4.java 执行程序 参数1 参数2 参数3。
注意事项: 在main方法中,我们可以直接调用main方法所在类的静态成员,
但是,不能直接访问非静态成员,必须创建一个实例对象后,才可以
通过对象来访问非静态成员。
public class TestMain{
public static int a = 100;
public int b = 200;
public static void main(String[] args) {
for(int i = 0; i < args.length; i++) {
// 在控制台执行输入 java TestMain jack peter mary
System.out.println("args["+i+"]值是:" + args[i]);
}
System.out.println(a) // 100 可以直接访问
// System.out.println(b) // 报错
System.out.println((new TestMain).b) // 200 必须创建类再访问
}
}
03-代码块
基本概念: 代码块又称为初始化块,属于类中的成员,将逻辑语句封装在方法体中,通过{}包围起来,类似于方法,但是没有方法名、没有返回、没有参数,只有方法体,而且不是通过对象或显示调用,而是在加载类时,或创建对象时隐式调用。
语法注意点:
{
public int num = 100;
}
static {
public int num1 = 100;
}
1.修饰符可选,要写的话只能写 static
2.代码块分为两类,带static称为静态代码块,否则称为普通代码块。
3.逻辑语句可以时任意逻辑语句。
自我理解:
1.相当于另一种形式的构造器(对于构造器机制的补充),可以做初始化使用。
2.如果多个重载的构造器都有重复的语句,可以抽取到代码块中,提高复用性。
注意细节:
1.static代码块称为静态代码块,作用是对类进行初始化,而且随类的加载而执行,因为类只会加载一次,所以只会执行一次,如果是普通代码块,每创建一个对象,就执行。
2.类加载的三个地方:
-创建对象实例时
-创建子类对象实例,父类也会被加载
-使用类的静态成员时
3.普通代码块,在创建实例对象的时,会被隐式调用,被创建一次调用一次。
4.创建一个对象时,代码的调用顺序:
1)调用静态代码块和静态属性初始化(这两个优先级一样,所以按照顺序执行)。
2)调用普通代码块和普通属性初始化(两个优先级一样,按照顺序执行)。
3)调用构造方法。
5.创建一个子类时(继承关系),他们的静态代码块,静态属性初始化,普通代码块,
普通属性初始化,构造方法的代码的调用顺序:
1)父类静态代码块和静态属性(优先级一样,顺序执行)
2)子类静态代码块和静态属性(优先级一样,顺序执行)
3)父类的普通代码块和普通属性(同上)
4)父类的构造器
5)子类的普通代码块和普通属性(同上)
6)子类的构造器
04-单例设计模式
基本概念: 单例模式,就是采取一定的方法保证整个软件系统中,对某个类只能存在一个对象实例,并且该类提供一个取得其对象实例的方法。
一、饿汉式
步骤如下:
1.构造器私有化
2.类的内部创建对象(静态对象,加载类的时候初始化对象,类只会加载一次,所以这个对象只能创建一次)
3.向外暴露一个静态的公共方法
public class Test {
public static void main(String[] args) {
// 通过类名调用静态方法
GirdFriend mary = GirdFriend.getInstance();
GirdFriend mary1 = GirdFriend.getInstance();
System.out.println(mary == mary1) // true
}
}
class GirdFriend {
private String name;
// 创建一个对象
private static GirdFriend instance = new GirdFriend("mary");
private GirdFriend(name){
this.name = name;
}
// 创建一个公共静态方法返回一个对象
public static GirdFriend getInstance() {
return instance;
}
public String getName(){
return name;
}
}
二、懒汉式
步骤如下:
1.构造器私有化
2.使用时,类的内部创建对象(先定义,但是不创建对象,调用getInstance在创建)
3.向外暴露一个静态的公共方法
public class Test {
public static void main(String[] args) {
// 通过类名调用静态方法
GirdFriend mary = GirdFriend.getInstance();
GirdFriend mary1 = GirdFriend.getInstance();
System.out.println(mary == mary1) // true
}
}
class GirdFriend {
private String name;
// 创建一个对象 必须时静态属性,这样静态方法才能调用
private static GirdFriend instance;
private GirdFriend(name){
this.name = name;
}
// 创建一个公共静态方法返回一个对象
public static GirdFriend getInstance() {
if(instance == null) { // 如果没有创建过,创建一个返回,已有对象就直接返回
instance = new GirdFriend("mary")
}
return instance;
}
public String getName(){
return name;
}
}
两种模式对比:
1.两者主要的区别在于创建对象的时机不同:饿汉式实在类加载就床架对象,而懒汉式是在使用时才创建。
2.饿汉式不存在线程问题,懒汉式存在线程安全问题。
3.饿汉式存在浪费空间的可能,因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费
了,懒汉式是在使用时创建,不存在这个问题。
4.在JavaSE标准类中,java.lang.Runtime就是经典单例模式。



