1 static关键字
1.1 static关键字的引入
- 当我们在编写一个类的时候,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过new关键字才会产生对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。
- 我们有时间希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份,例如所有的中国人都由一个中国国籍,每一个中国人都共享这个国家名称,而不必再每一个中国人的实例对象中都单独分配一个代表国家名称的变量。
1.2 类属性、类方法的设计思想
- 类属性作为该类的各个对象之间共享的变量。在设计类的时候,分析哪些属性不因对象的不同而改变,将这些属性设置为类属性。相应的方法设置为类方法。
- 如果方法与调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。
1.3 static关键字的使用范围
- 在Java中,可以用static关键字修饰属性、方法、代码块和内部类。
1.4 static关键字修饰的成员的特点
- 随着类的加载而加载。
- 优先于对象存在。
- 修饰的成员,被所有对象所共享。
- 访问权限允许的情况下,可以不创建对象,直接使用类名调用。
1.5 使用static修饰属性(类属性)
- 根据static修饰属性,分为静态变量(类变量或类属性)和非静态变量(实例变量):
- ①实例变量:我们创建了类的多个对象,每个对象都独立拥有一套类中的非静态属性。当修饰其中一个对象中的非静态属性的时候,不会导致其他对象中同样的属性值被修改。
- ②静态变量:我们创建了类的多个对象,多个对象之间共享同一个静态变量。当通过某一个对象修饰静态变量的时候,会导致其他对象调用此静态变量的时候,是修改过的。
1.6 使用static修饰方法(类方法)
- 在没有对象实例的时候,可以使用类名.方法名()的形式访问static修饰的类方法。
- 在static方法内部只能访问类的static修饰的属性或方法,不能访问非static的结构。
- static方法内部既不能有this,也不能有super。
- static修饰的方法不能被重写。
2 单例设计模式
2.1 什么是设计模式?
- 设计模式是在大量的实际中总结和理论化之后优选的代码结构、编程风格以及解决问题的思考方式。
- 设计莫斯免去了我们自己再思考和摸索,设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱。
2.2 单例设计模式
- 所谓的单例设计模式,就是采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个获取其对象实例的方法。如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但是,在类的内部依然可以产生该类的对象。因为在类的外部开始还无法得到该类的对象,只能调用类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。
2.3 单例设计模式的实现--饿汉式
- 示例:
package day14;/** * 单例模式的饿汉式 */public class Singleton { private static Singleton singleton = new Singleton(); /** * 私有化类的构造器 */ private Singleton() { } public static Singleton getInstance() { return singleton; }}
2.4 单例设计模式的实现--懒汉式
- 示例:
package day14;/** * 单例模式的饿汉式 */public class Singleton { private static Singleton singleton; /** * 私有化类的构造器 */ private Singleton() { } public static Singleton getInstance() { if (null == singleton) { singleton = new Singleton(); } return singleton; }}
2.5 单例模式的优点
- 由于单例模式只产生一个实例,减少了系统性能的开销,当一个对象的产生需要比较多的资源的时候,如读取配置、产生其他依赖对象时,则可以通过在应用启动的时候直接产生一个单例对象,然后永久驻留内存的方式来解决。
2.6 单例设计模式的应用场景
- 网站的计数器,一般也是单例模式实现,否则难以同步。
- 应用程序的日志应用,一般都使用单例模式实现,一般是由于共享的日志文件一直处于打开状态,因此只能有一个实例去操作,否则内容不好追加。
- 数据库连接池,一般也采用单例设计模式,因为数据库连接是一种数据库资源。
- 项目中,读取配置文件的类,一遍也只有一个对象。没必要每次使用配置文件数据,都生成一个对象去读取。
3 代码块
3.1 代码块的作用
- 对Java中的类和对象进行初始化。
3.2 代码块的分类
- 静态代码块(static代码块):被static关键字修饰的代码块。通常,静态代码块用来给静态变量初始化。
- 非静态代码块(非static代码块):没有被static关键字修饰的代码块。
3.3 静态代码块和非静态代码块的区别
3.3.1 静态代码块
- 可以有输出语句。
- 不可以对非静态的属性初始化。即不可以调用非静态的属性和方法。
- 如果有多个静态代码块,那么按照从上到下的顺序依次执行。
- 静态代码块的执行要先于非静态代码块。
- 静态代码块随着类的加载而执行,并且只执行一次。
3.3.2 非静态代码块
- 可以有输出语句。
- 除了调用非静态的结构外,还可以调用静态的变量或方法。
- 如果有多个非静态的代码块,那么按照从上到下的顺序依次执行。
- 每次创建对象的时候,都会执行依次,并且优先于构造器执行。
3.4 代码块的应用示例
- 示例:
package day14;public class Person { private String name; private Integer age; public static String country = "中国"; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } static { System.out.println("我是静态代码块"); } { System.out.println("我是非静态代码块"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } public static void show() { System.out.println(country); }}
package day14;public class PersonTest { public static void main(String[] args) { String country = Person.country; //执行静态代码块 Person person = new Person();//执行非静态代码块 }}
4 final关键字
4.1 final关键字的特点
- 被final关键字修饰的类不可以继承。
- 被final关键字修饰的方法不可以重写。
- 被final关键字修饰的变量:
- 如果修饰的是属性(称为常量,根据规范需要大写,如果多个单词,中间用"_"隔开):显示初始化,代码块中初始化,构造器中初始化。
- 如果修饰的是局部变量,必须赋值。如果修饰的是形参,不可以修改。