java-面向对象4-代码块、static关键字和final关键字


前言

本文主要介绍java面向对象中static关键字、代码块和final关键字

1、关键字:static

static关键字的引入:
有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份。
java将static关键字修饰的成员称为类成员:

  • 类属性(class Variable):作为该类各个对象之间共享的变量。在设计类时,分析哪些属性不因对象的不同而改变
  • 类方法:如果方法与调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用:
    • 没有对象的实例时,可以用类名.方法名()的形式访问由static修饰的类方法
    • 在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。

static的使用范围:
在Java类中,可用static修饰属性、方法、代码块、内部类
static修饰的成员的特点:

  • 随着类的加载而加载
  • 优先于对象存在
  • 修饰的成员,被所有对象所共享
  • 访问权限允许时,可不创建对象,直接被类调用
    注意:
  • 在静态的方法内,不能使用this关键字、super关键字
  • 关于静态属性和静态方法的使用,从生命周期的角度去理解
  • static修饰的方法不能被重写

单例 (Singleton)设计模式:
设计模式:是在大量的实践中总结和理论化之后优选的代码结构、编程风格、 以及解决问题的思考方式。设计模式免去我们自己再思考和摸索。
单例设计模式: 采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法

  • 如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无 法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的

单例(Singleton)设计模式-饿汉式

public class Singleton {
	// 1.私有化构造器
	private Singleton() {
	}

	// 2.内部提供一个当前类的实例,此实例也必须静态化
	private static Singleton single = new Singleton();

	// 3.提供公共的静态的方法,返回当前类的对象
	public static Singleton getInstance() {
		return single;
	}
}

单例(Singleton)设计模式-懒汉式

public class Singleton {
	/**
	 * 存在线程安全问题
	 */
	// 1.私有化构造器
	private Singleton() {
	}

	// 2.内部提供一个当前类的实例,此实例也必须静态化
	private static Singleton single;

	// 3.提供公共的静态的方法,返回当前类的对象
	public static Singleton getInstance() {
		if (single == null) {
			single = new Singleton();
		}
		return single;
	}
}

单例模式的优点:
由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。

单例(Singleton)设计模式-应用场景

  • 网站的计数器,一般也是单例模式实现,否则难以同步。
  • 应用程序的日志应用,一般都使用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
  • 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。
  • 项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置
    文件数据,都生成一个对象去读取。
  • Application 也是单例的典型应用
  • Windows的Task Manager (任务管理器)就是很典型的单例模式
  • Windows的Recycle Bin (回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。

2、类的成员:代码块(初始化块)

代码块(或初始化块)的作用:

  • 对Java类或对象进行初始化

代码块(或初始化块)的分类:

静态代码块(static block):一个类中代码块若有修饰符, 则只能被static修饰,static代码块通常用于初始化static的属性

  • 可以有输出语句。
  • 可以对类的属性、类的声明进行初始化操作。
  • 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
  • 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
  • 静态代码块的执行要先于非静态代码块。
  • 静态代码块随着类的加载而加载,且只执行一次。
class Person {
	public static int total;
	static {
		total = 100;//为total赋初值
	}…… // 其它属性或方法声明
}

非静态代码块:没有使用static修饰的

  • 可以有输出语句。
  • 可以对类的属性、类的声明进行初始化操作。
  • 除了调用非静态的结构外,还可以调用静态的变量或方法。
  • 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
  • 每次创建对象的时候,都会执行一次。且先于构造器执行。

程序中成员变量赋值的执行顺序(由父及子,静态先行):
在这里插入图片描述

//总结:由父及子,静态先行
class Root {
	static {
		System.out.println("Root的静态初始化块");
	}
	{
		System.out.println("Root的普通初始化块");
	}

	public Root() {
		super();
		System.out.println("Root的无参数的构造器");
	}
}

class Mid extends Root {
	static {
		System.out.println("Mid的静态初始化块");
	}
	{
		System.out.println("Mid的普通初始化块");
	}

	public Mid() {
		super();
		System.out.println("Mid的无参数的构造器");
	}

	public Mid(String msg) {
		// 通过this调用同一类中重载的构造器
		this();
		System.out.println("Mid的带参数构造器,其参数值:" + msg);
	}
}

public class Leaf extends Mid {
	static {
		System.out.println("Leaf的静态初始化块");
	}
	{
		System.out.println("Leaf的普通初始化块");
	}

	public Leaf() {
		// 通过super调用父类中有一个字符串参数的构造器
		super("尚硅谷");
		System.out.println("Leaf的构造器");
	}

	public static void main(String[] args) {
		System.out.println("-----main方法------");
		new Leaf();
		System.out.println("-------------------");
		new Leaf();
//		Root的静态初始化块
//		Mid的静态初始化块
//		Leaf的静态初始化块
//		-----main方法------
//		Root的普通初始化块
//		Root的无参数的构造器
//		Mid的普通初始化块
//		Mid的无参数的构造器
//		Mid的带参数构造器,其参数值:尚硅谷
//		Leaf的普通初始化块
//		Leaf的构造器
//		-------------------
//		Root的普通初始化块
//		Root的无参数的构造器
//		Mid的普通初始化块
//		Mid的无参数的构造器
//		Mid的带参数构造器,其参数值:尚硅谷
//		Leaf的普通初始化块
//		Leaf的构造器
	}
}

3、关键字:final

在Java中声明类、变量和方法时,可使用关键字final来修饰,表示“最终的”。
说明:

  • final标记的类不能被继承。提高安全性,提高程序的可读性。
    • String类、System类、StringBuffer类
  • final标记的方法不能被子类重写。
    • 比如:Object类中的getClass()。
  • final标记的变量(成员变量或局部变量)即称为常量。名称大写,且只
    能被赋值一次。
    • final标记的成员变量必须在声明时或在每个构造器中或代码块中显式赋 值,然后才能使用。
    • final double MY_PI = 3.14;
final int WIDTH = 0;
	final int LEFT;
	final int RIGHT;
	
	{
		LEFT = 1;
	}
	
	public FinalTest(){
		RIGHT = 2;
	}
  • final修饰局部变量:尤其是使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参。一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值。
public void show(){
		final int NUM = 10;//常量
//		NUM += 20;//错误
	}
	
	public void show(final int num){
//		num = 20;//编译不通过
		System.out.println(num);
	}
  • static final:全局常量
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值