文章目录
一、static关键字
static用来修饰 属性、方法、代码块、内部类
静态变量和实例变量的区别
1、个数
静态变量在内存空间中只有一份,被类的多个对象所共享
实例变量每个实例都有
2、内存位置
静态变量在JDK6和之前存放在方法区,JDK7之后存放在堆空间
实例变量存放在堆空间的对象实体中
3、 加载时机
静态变量随着类的加载而加载,只会加载一次,类只加载一次,所以静态变量也只有一份
实例对象随着对象的创建而加载,每个对象拥有一份实例变量
4、调用者
静态变量可以被类直接调用,也可以使用对象调用
实例变量只能使用对象调用
5、判断是否可以调用,从生命周期的角度解释
类 可以调用类变量 不可以调用实例变量
对象 可以调用类拜变量 也可以调用实例变量
6、消亡时机
静态变量随着类的卸载而消亡
实例变量随着对象的消亡而消亡
静态方法内可以调用静态的属性和方法,不可以调用非静态的方法
static修饰的方法内,不能使用super和this
一般方法中用了静态变量或者方法要作为工具类 我们会用静态方法来实现
二、单例(Singleton)设计模式
创建型模式
简单工厂模式、工厂方法模式、抽象工厂模式、创建者模式、原型模式、单例模式
结构型模式
外观模式、适配器模式、代理模式、装饰模式、桥接模式、组合模式、享元模式
行为型模式
模板方法模式、观察者模式、状态模式、策略模式、职责链模式、命令模式、访问者模式、调停者模式、备忘录模式、迭代器模式、解释器模式
单例模式:在整个软件系统中,某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法
实现思路:
一个类如果只能产生一个对象,那么必须要将类的构造器的访问权限设置为private,并且不可以new,类的内部依然可以产生类的对象,同时类的外部只能调用该类的某个静态方法,返回类内部创建的对象,静态方法只能访问类的静态成员变量,所指向类内部产生的该类的变量也必须定义成静态的
饿汉式单例模式 代码实现(笔试推荐写饿汉式 原因:保证线程安全)
饿汉式属于立即加载,随着类的加载,当前唯一实例就创建好了
优点:写法简单,由于内存中较早加载,使用更方便、更快,是线程安全的
缺点:懒汉式生命周期长 更容易出现内存泄露,内存中占用时间较长
public class BankTest {
public static void main(String[] args) {
Bank instance = Bank.getInstance();
System.out.println(instance);
}
}
class Bank{
// 1、构造器私有化
private Bank(){
}
// 2、在类的内部创建当前类的实例 属性必须为static
private static Bank instance=new Bank();
//3、使用get方法获取当前类的实例,必须声明为static
public static Bank getInstance(){
return instance;
}
}
懒汉式单例模式 代码实现
懒汉式属于延迟加载,在需要使用的时候进行创建。
可能会在多线程中出现线程安全问题
优点:在需要的时候进行创建,节省内存时间。
缺点:线程不安全(多线程环境下)
public class GirlFriendTest {
public static void main(String[] args) {
}
}
class GirlFriend{
//1、类的构造器私有化
private GirlFriend(){
}
//2、声明当前类的实例
private GirlFriend instance=null;
//3、通过get方法获取当前类的实例,如果未创建对象,则在方法内部进行创建
public GirlFriend getInstance(){
if (instance==null){
instance=new GirlFriend();
}
return instance;
}
}
单例模式应用场景
Windows的Task Manager 任务管理器
Windows的Recycle Bin 回收站
Application
应用程序的日志应用
数据库连接池的设计
三、main函数
main()静态,不能直接访问类中的非静态成员,必须创建该类的一个实例对象。
可以看做是一个普通的静态方法
可以看做是程序的入口,格式是固定的
public static void main(String args[]){}
与控制台交互的两种方式
Scanner
main()形参进行传值
四、代码块
代码块的作用,初始化类或对象的信息(类或对象的成员变量)
只能使用static修饰或者就是不修饰
分为静态代码块和非静态代码块两种
静态代码块
随着类加载自动执行,只执行一次
用来初始化类的信息
内部可以声明变量、调用属性或方法、编写输出语句等操作
静态代码块的执行要先于非静态
多个静态代码块,按照声明的先后顺序执行
静态代码块的内部只能调用静态的结构(静态属性和方法)不可以调用非静态结构
非静态代码块
随着对象的创建执行
创建当前类的一个实例,就会执行一次非静态代码块
用来初始化对象实例的信息
内部可以声明变量、调用属性或方法、编写输出语句等操作
如果声明有多个非静态代码块,则按照声明先后顺序执行
非静态代码块内部可以调用静态结构也可以调用非静态结构
public class StaticDemo {
public static void main(String[] args) {
System.out.println(1);
People people1 = new People();
People people2 = new People();
System.out.println(people1.getAge());
System.out.println(people2.getAge());
}
}
class People {
static private int age;
{
age=10;
System.out.println(age);
}
static {
age=20;
System.out.println(age);
}
public int getAge(){
return age;
}
}
五、属性的赋值
非静态变量赋值的位置
1、默认初始化
2、显式初始化
3、构造器初始化
4、代码块中初始化
5、有对象后,用点运算或者方法进行初始化
执行顺序 1-2/4(看谁先声明)-3-5
刚开始调用方法前,是将所有的方法加载到方法区,调用前加载了,那么就可以调用成功。
显式赋值比较适合每个对象属性值相同的场景
构造器比较适合每个对象属性值不同的场景
代码块用的少一些