06_代码块

代码块

定义

由若干条Java语句组成,并且用一对大括号{}括起来的结构,叫做代码块

分类

根据定义的位置不同,声明方式不同分类

  1. 局部代码块
    语法:{}
    位置:定义在局部位置

  2. 构造代码块
    语法:{}
    位置:成员位置
    说明:构造代码块内部定义的变量 —> 局部变量 —> 只在构造代码块内部生效

  3. 静态代码块
    语法:static{}
    位置:成员位置
    说明:静态代码块内部定义的变量 —> 局部变量 —> 静态代码块内部生效

  4. 同步代码块

synchronized(){
	// 同步代码块
}

构造代码块

作用

给成员变量赋值用的

给成员变量赋值的方式

  1. 默认赋值
  2. 显示赋值
  3. 构造方法赋值
  4. 构造代码块

研究赋值的顺序

  1. 默认赋值永远是第一步
  2. 构造代码块如果写在上面,则构造代码块先执行
    构造代码块如果写在下面,则显示赋值先执行
    结论:构造代码块跟显式赋值谁先执行 >>>>> 写在上面的先执行
  3. 构造方法赋值永远是最后一步

注意事项

  1. 经过反编译操作(通过IDEA),构造代码块中的内容被加入到了每个构造方法中前面
  2. 整个过程中,构造代码块和显示赋值的代码只会执行一次,不会执行多次

静态代码块

作用

可以被认为在类加载过程中自动调用的一个静态的方法,可以给静态成员赋值

给静态成员赋值的手段
  1. 默认赋值
  2. 显示赋值
  3. 静态代码块,特点是在类加载过程中一定会执行
赋值顺序
  1. 默认赋值
  2. 看一下静态代码块和显式赋值谁在上面(书写顺序)
    结论:谁在上面谁先执行,先执行的内容会被后执行的内容覆盖掉
  3. 构造方法
用途
  1. 复杂的静态成员变量的赋值
  2. 如果一段代码,在类的全局,从始至终,只运行一次,就可以写到静态代码块中。(类似于类加载只加载一次)
注意事项
  1. 静态代码块在类加载过程中被当做自动执行的静态方法,不能访问非静态
  2. 当需要使用复杂的代码给静态成员变量赋值的时候,可以使用静态代码块
  3. 静态代码块也经常被用来测试类加载的顺序。(重要)

对象的结构

在这里插入图片描述

类加载的过程

  1. 加载
    通过类加载器(ClassLoader)加载类,读取字节码文件,.class文件,读取到内存中(二进制文件),在这个过程中,在内存中会生成这个类所对应的字节码文件对象(java.lang.Class),这个字节码文件对象包含了类中的所有信息(All)
  2. 链接
    (1)验证:主要进行字节码文件的正确性的校验
    (2)准备:为类中的静态成员分配内存,赋予默认初始值
    (3)解析:把符号引用(用一组符号来描述被引用的目标)替换为直接引用(真实的内存地址)
  3. 初始化
    执行静态代码块中的内容,给静态成员显示赋值

导包

package关键字

作用

写在java文件的第一行
表明java文件中的类是属于哪个包

注意事项

  1. 包名在书写时,如果存在多级包名,需要使用用.隔开
  2. package声明必须处在一个Java文件有效代码的第一行,否则会报错
    • 注释不算有效代码,将package声明放在注释下面也是可以的
    • 建议将package声明永远放在Java源文件真正意义上的第一行
  3. 多数情况下,我们使用idea新建Java文件是无需关系package声明的,因为idea会自动生成
    • 但是当你从网上或者其它途径弄到的一些代码,可能会出现包名错乱的情况
    • 这时建议直接删除package声明,然后"Alt + 回车"类名报错的地方即可

全限定类名

import关键字

语法

import 全限定类名;

注意事项

  1. import导包语句应该放在package声明之后,有效代码之前。

    正常情况下,我们使用某个类时,IDEA会自动导包,不用太关心这条语句的位置。

    一般只需要注意不要用IDEA导错包就可以了。

  2. 像String、System、Math等常用类很明显不是同包下的类,但我们并没有进行导包操作。

    1. 这是因为在Java当中的,“java.lang包”是Java的核心类包,具有隐式的导包。
    2. 注意"java.lang包"下的所有类,是隐式的导入了每个Java类,而不是没有导入!
  3. 实际上完全可以不导包去使用不同包下类,这时要明确指出这个类的所属包,也就是要使用全限定类名。

    但是一般情况下,全限定类名都很长,导包仍然是更好的手段。

  4. 但是导包总不是都好用,在极少的情况下:

    比如,在Demo类中,想要同时访问两个包onepackage、anotherpackage下的两个Student类。

    咋办?

    很简单,其中一个Student类使用全限定类名,另一个导包或者就近原则直接使用就可以了。

(当然条件允许的情况下,干脆把其中一个Student改名会更好。)

智能导入

语法

import + 包名.*;
eg:

import java.util.*;

静态导入

import还可以和static一起使用,称之为静态导入
普通import导入导入的是某个类,而静态导入导入的是静态成员(变量和方法)

以往我们访问不同包下的类的静态成员,是通过类名.静态成员名的形式访问的

而如果使用静态导入的语法将这些不同包的类当中的静态成员导入,就可以省略相应的类名~

语法
import static 全限定类名.*;
import static 全限定类名.静态成员;

包的作用

  1. 在工程中用于组织Java文件,分类。

  2. 类名的空间管理,同包禁止同名类,避免类名冲突。

    注:前两点和操作系统中的文件夹作用是一致的。

  3. 提供包一级的封装及访问权限控制。(面向对象后面的知识)

包的命名

  1. 全部小写英文单词,实际开发中多以反转公司域名为开头。
    eg:com.baidu.package1

  2. 如果是名词,使用单数形式,不要用复数形式。

编译单元

  1. 一个Java源代码文件(Java文件)称为一个编译单元。
  2. 一个Java源代码文件由三部分组成:
    1. 所属包的声明,即package声明。
    2. 导入声明。即import声明。
    3. 主体声明。
  3. 一个编译单元只能有一个public class,该类的类名必须与文件名相同。但可以允许有多个非public class。经过编译后,该编译单元下的所有class都会生成对应的、独立的字节码文件。

访问权限控制符

在Java语言中,一切事物(类和类的所有成员)都具有(或显示定义或隐式定义的)访问权限,而这种语言层面的访问权限控制,是由访问权限修饰符实现的。

4个访问级别

  1. private
    只能是同类中进行访问

  2. 默认权限(缺省)
    只能是同包中进行访问

  3. protected

  4. public
    同包或者不同包都可以访问(相当于没有访问权限)

注意事项

  1. 代码块没有访问权限
  2. 局部变量没有访问权限

class访问级别

只有两个访问级别:

  1. public
  2. 默认

在这里插入图片描述

作用

  1. 专门提供给外界使用的,推荐使用的,用public。告诉别人:这里是你需要关注、了解和使用的地方。

    所有明确提供给外界使用,实现功能的方法,需要用public修饰。

  2. 不应该触碰的地方,用私有private修饰,告诉别人:这里你不需要你看,也不需要你管。

    具体的案例是:

    1. 工具类,既然所有的方法,都可以直接用“类名.”去调用,不需要创建对象!

      既然不需要对象,那就干脆不要创建对象,直接把这个功能去掉!

      所有工具类,都应该私有化无参构造方法!!

    2. 类中需要提供给外界使用的方法的实现过程中,经常需要一些“中间的过程”方法。

      这些方法不需要提供给外界使用,仅作为内部实现功能使用。

      所有类中的"中间方法"都应该私有化它们!

    3. 工厂设计模式。

      指的是不通过自身构造器创建对象,而是通过“工厂”去创建对象,这时类的构造器应该私有。

工厂设计模式

定义

一种创建对象的方式,只需要告诉我生产什么对象,生产对象的过程交给工厂去做,不需要关心内部的实现细节。

举例

public class StudentFactory{
	private StudentFactory(){
	
	}
	
	// 提供一个静态的方法,给外部访问
	public static Student getInstance(String className, String name, int age)
	throws Exception
	{
		// 要使用反射
		Class<?> c = Class.forName(className);
		
		Constructor<?> constructor = c.getDeclaredConstructor(String.class, int.class);
		constructor.setAccessible(true);

		// 创建构造方法
		Student student = constructor.newInstance(name, age);
		// 最终 --->  返回一个学生对象
		return student;
	}
}

好处

  1. 尽量私有化,方便自己修改代码,隐藏实现细节。

  2. 如果不能私有化,那也应该尽量少的给予访问权限,先从默认权限开始考虑。

  3. 只有确定这个结构,一定需要在外部(尤其是不同包下)被访问时,才考虑给public尽量少给public

    权限这个东西,要吝啬,不要"大方"!

单例设计模式

定义

单例设计模式是一种应用程序维护实例的方式,
单例即1个,应用程序中只有1个唯一的实例对象(全局共享的)。

应用场景

  1. 回收站
  2. 统计用户访问量,计数器(单例)

实现步骤

  1. 构造方法私有
  2. 提供一个自身的全局的静态成员变量
  3. 提供一个public的静态方法

两种模式

  • 懒汉模式(懒加载)
    • 懒汉指的是用到的时候才去创建对象
  • 饿汉模式(立即加载)
    • 饿汉指的是不管用不用, 先去把对象创建好

懒汉模式(懒加载)实现单例(线程不安全)

public class Singleton{
	// 提供一个全局的自身成员变量
	private static Singleton instance;

	// 构造方法私有
	private Singleton(){

	}
	
	// 提供一个静态的public的访问,给外部访问,从而获得唯一的实例对象
	public static Singleton getInstance(){
		// 做判断
		if( null == instance){
		
			instance = new Singleton();
		}

		// 最终要返回这个唯一的对象
		return instance;
	}
}

饿汉模式(立即加载)实现单例(线程安全)

public class Singleton{
	// 提供一个全局的自身成员变量
	private static Singleton instance = new Singleton();

	// 构造方法私有
	private Singleton(){

	}
	
	// 提供一个静态的public的访问,给外部访问,从而获得唯一的实例对象
	public static Singleton getInstance(){
		
		// 最终要返回这个唯一的对象
		return instance;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coo1heisenberg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值