main方法语法
深入理解main方法的形式:public static void main(String[] args){}
- main方法是虚拟机调用
- java虚拟机需要调用类的main方法,所以该方法的访问权限必须是public
- java虚拟机在执行main方法是不必创建对象,所以该方法必须是static
- 该方法在接收String类型的参数,该数组中保存执行Java命令时传递给运行类的参数
- Java执行程序 参数1 参数2 参数3
- 特别提示
在main方法中,我们可以直接调用main方法所在类的静态方法或静态属性,但是,不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过该对象去访问类中的非静态成员。
代码块
-
基本介绍
代码块又称为初始化块,属于类中的成员【即 是类的一部分】,类似于方法,将逻辑语句封装在方法体中,通过{}包围起来,但是和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象或类显示调用,而是加载类时,或创建对象时隐式调用 -
基本语法
[修饰符]{
代码
}; -
注意:
- 修饰符可选,要写的话,也只能写static
- 代码块分为两类,使用static修饰的叫静态代码块,没有static修饰的叫普通代码块(非静态代码块)
- 逻辑语句可以为任何逻辑语句(输入,输出,方法调用,循环,判断等)
- ; 可以写,也可以省略
-
代码块的好处
- 相当于另外一种形式的构造器(对构造器的补充机制),可以做初始化操作
- 如果多个构造器中都有重复语句,可以后渠道初始化块中,提高代码的重用性
-
代码块的注意事项和细节讨论
- static代码块也叫做静态代码块,作用就是对类进行初始化,而且随着类的加载而执行,并且只会执行一次。如果是普通代码块,每创建一个对象,就执行。
- 类什么时候加载
- 创建对象实例时(new)
- 创建子类对象实例,父类也会被加载(先加载父类)
- 使用类的静态成员时(静态属性,静态方法)
- 普通代码块,在创建对象实例时,会被隐式调用,被创建一次,就会调用一次,如果使用类的静态成员时,普通代码并不会被执行。(因为在嗲用类的静态成员时,不需要创建实例对象)
- 创建一个对象时,在一个类 调用顺序是
- 调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们的定义顺序调用)
- 调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块和多个普通变量初始化,则按他们的定义顺序调用)
- 调用构造方法
- 构造方法(构造器)的前面其实隐含了super()和调用普通代码块,静态相关的代码块,属性初始化,在类加载时,就执行完毕了,因此是优先于构造器和普通代码快执行的
- 创建一个子类对象时(继承关系),他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造器的调用顺序如下:
- 父类的静态代码块和静态属性初始化(优先级一样,按定义顺序执行)
- 子类的静态代码块和静态属性初始化(优先级一样,按定义顺序执行)
- 父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
- 父类的构造方法
- 子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
- 子类的构造方法
- 个人理解:在创建对象时,先进行类的加载,首先加载父类,其次是子类,故先执行父类的静态代码块和静态属性初始化,再是子类。然后在调用子类的构造方法之前,先执行super(),故先执行父类的构造方法,在执行父类的构造方法之前,执行其普通代码块和普通属性的初始化,再执行构造方法。父类的构造方法执行结束后,执行子类的普通代码块和普通属性初始化,再执行子类的构造方法。
- 静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员
单例设计模式
-
什么是设计模式
- 静态方法和属性的经典应用
- 设计模式是再大量的实践中总结和理论化之后优选的代码结构,编程风格,以及解决问题的思考方式。
-
什么是单例模式
- 所谓的单例设计模式,就是采用一定的方法保证在整个的软件系统中,对某个类只能存在一个对象的实例,并且该类只提供一个取得其对象实例的方法
- 单例模式有两种方式:饿汉式,懒汉式
- 构造器私有化=>防止直接new对象
- 类的内部创建对象
- 向外暴露一个静态的公共方法=>getInstance(获取实例)
-
饿汉式:随着类的加载,类的实例对象就会被创建,可能造成对象被创建了,但未使用,造成资源浪费
public class SingleTon{ public static void main(String[] args) { System.out.println(GirlFriend.s); } } class GirlFriend{ public static String s = "love"; private String name; //私有实例对象(在类加载时被创建) private static GirlFriend girlFriend = new GirlFriend("小红"); //私有化构造函数 private GirlFriend(String name){ this.name = name; System.out.println("构造器。。。。。。"); } //公共静态方法,获取实例对象 public static GirlFriend getInstance(){ return girlFriend; } }
-
懒汉式:类的实例对象在使用时才被创建
public class SingleTon1{ public static void main(String[] args) { System.out.println(Cat.s); } } class Cat{ public static String s = "love"; private String name; //私有实例对象(在类加载时被创建) private static Cat cat ; //私有化构造函数 private Cat(String name){ this.name = name; System.out.println("构造器。。。。。。"); } //公共静态方法,获取实例对象 public static Cat getInstance(){ if(cat ==null){ cat = new Cat("小花"); } return cat; } }
-
懒汉式vs饿汉式
- 二者最主要的区别在于拆功能键对象的时机不同:饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建的
- 饿汉式不存在线程安全问题,懒汉式存在线程安全问题。
- 饿汉式存在资源浪费的可能,因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费了,懒汉式是使用时才创建的,就不存在这个问题
枚举和注解
枚举
- 自定义枚举
- 构造器私有化
- 本类内部创建一组对象
- 对外暴露对象(通过为对象添加public final static修饰符)
- 可以提供get方法,不提供set方法
class Season{ private String name; public final static Season SPRING= new Season("春天"); public final static Season SUMMER= new Season("夏天"); public final static Season AUTUMN= new Season("秋天"); public final static Season WINTER= new Season("冬天"); //1.将构造器私有化,防止被直接New对象 //2.去除setXXX方法,防止属性被修改 //3.在Season内部直接创建固定的对象 //4.优化:可以加入final修饰符 private Season(String name){ this.name = name; } public String getName() { return name; } }
- 使用enmu关键字
//演示使用enmu关键字 enum Season2{ //常量名(实参列表); //如果有多个常量(对象),使用逗号(,)间隔即可 //如果用enum 实现枚举,则常量(对象)一定要放在最前边 SPRING("春天"), SUMMER("夏天"), AUTUMN("秋天"), WINTER("冬天"); private String name; private Season2(String name){ this.name = name; } public String getName() { return name; } }
- enum关键字实现枚举使用注意事项
- 当我们使用enum关键字开发一个枚举类时,默认会继承Enum类,而且是final类
- 传统的public final static Season SPRING = new Season(“春天”);简化成SPRING(“春天”),这里必须知道他调用的时哪个构造器
- 如果使用无参构造器创建枚举独享,则实参列表和雄安括号都可以省略
- 当有多个枚举对象时,使用(,)间隔,最后一个使用(;)结尾
- 枚举对象必须放在枚举类的首行
- enum关键字实现枚举使用注意事项
- 注意事项
- 使用enum关键字后,就不能在继承其他的类了,因为enum会隐式继承Enum,而java是单继承机制
- 枚举类和普通的类一样,可以实现接口
注解
- 注解的理解
- 注解(Annotation)也被称为元数据(Metadata),用于修饰解释 包,类,方法,属性,构造器,局部变量等数据信息
- 和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息
- 在javaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等,在javaEE中注解占据了重要的角色,例如用来配置应用程序的任何切面,代替javaEE旧版中遗留的繁重代码和XML配置等
- 基本注解介绍
使用注解时要在其前面增加@符号,并把该注解当成一个修饰符使用。用于修饰它支持的程序元素- 三个基本的注解:
- @Override:限定某个方法,是重写父类的方法,该注解只能用于方法
- @Deprecated:用于表示某个程序元素(类,方法等)已过时
- @SuppressWranings:抑制编译器警告