JavaSE自学笔记014_Real(代码块、字节码、设计模式)
一、代码块
代码块又称为初始化块,属于类中的成员,他是将逻辑语句封装在方法体中,通过{ }包裹。代码块没有方法名,没有参数,没有返回值,只有方法体,而且不通过对象或类进行显式的调用,他会在类记载或创建对象是主动的隐式调用。
(一)静态代码块
一个类被加载时被调用一次,常用在需要做一些全局初始化的工作。
static{
}
(二)实例代码块
每次创建实例,会被调用依次,其实用很少
{
}
举个例子:
public class Test {
//静态代码块
static {
System.out.println("I am static code block.");
}
//实例代码块
{
System.out.println("I am a instance code block.");
}
public static void main(String[] args) {
new Test();
new Test();
}
}
输出结果:
I am static code block.
I am a instance code block.
I am a instance code block.
(三)构造器、静态代码块,实例代码块的执行顺序(子类、父类)
//子类代码实现
public class Son extends Test{
//子类构造器
public Son() {
System.out.println("这是子类的构造器!");
}
//子类静态代码块
static {
System.out.println("这是子类的静态代码块");
}
//子类实例代码块
{
System.out.println("这是子类的实例代码块");
}
}
//父类代码实现
public class Test {
//父类构造器
public Test() {
System.out.println("这是父类构造器");
}
//父类静态代码块
static {
System.out.println("这是父类静态代码块");
}
//父类实例代码块
{
System.out.println("这是父类实例代码块");
}
public static void main(String[] args) {
new Son();
}
}
输出结果:
这是父类静态代码块
这是子类的静态代码块
这是父类实例代码块
这是父类构造器
这是子类的实例代码块
这是子类的构造器!
二、静态方法和静态变量
(一)
static关键字修饰。
用static修饰的类方法不需要实例化对象再进行调用,而是直接就可以调用成员方法
public class Test2 {
public static String name = "小李";
public static void SayHello(){
System.out.println("Hello World!");
}
public static void main(String[] args) {
Test2.SayHello();
System.out.println(Test2.name);
}
}
输出结果:
Hello World!
小李
分析字节码,可以了解到:
1、静态的变量或者静态方法是存在方法区的,其他的方法也是在方法区(永久带,元空间)
2、他们不属于实例对象,只是存在于方法区,调用要直接使用类名.方法名的方式调用。
(四)实例方法和静态方法相互调用
在Java中调用实例方法,必须要有主体,也就是实例化的对象,
在同一个类中直接调用时默认省略了this,而在静态方法中没有this,所以在静态方法中调用需要先实例化对象,也就是需要先new一个对象,在进行调用。
而静态方法无论在哪里都是类名.方法名调用,当然同一个类的静态方法之间调用可以省略类名,建议还是写上。
(五)应用场景
做一些工具类,用来直接使用,方便实用。
1、使用金太累完成一些工具性质的类
2、使用静态类完成一些全局只有一份的常量类的定义,也叫做静态常量。(静态常量字母全部大写!!!)
一般都会用static 和 final一起修饰:public static final String DEFAULT_CHARSET = "UTF-8;"
三、内部类
**内部类:**是在一个类的内部进行其他类结构的嵌套操作。
public class Outer {
public Outer() {
System.out.println("Outer");
}
public void test(){
Inner inner = new Inner();
}
public class Inner {
public Inner() {
System.out.println("Inner");
}
}
//静态内部类,在工程中一般用到的都是静态内部类
private static class StaticInner{
static {
System.out.println("Static Inner Class.");
}
}
public static void main(String[] args) {
Outer outer = new Outer();
outer.test();
}
}
四,单例设计模式
单例设计模式,是一种常见的软件设计模式,用过单例设计模式可以保证系统中,应用该模式的每一个类都只有一个实例,即一个类只有一个对象实例。
具体的思路:
(1)别人不能new实例,所以要构造器私有化,使其不能在类的外部通过new关键字实例化类的对象。
(2)在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型
(3)定义一个静态方法返回这个唯一的对象。
1、饿汉式:
力计加载就是使用类的时候已经将对象创建完毕(不管以后会不会使用到该实例化对象,先创建了再说,很着急的样子,所以被称为饿汉),常见的实现办法就是直接new实例化。
public class Singleton {
// 初始化一个
private static final Singleton INSTANCE = new Singleton();
// 让别人不能new 将无参构造器私有化,保证别人不能实例化对象
private Singleton(){
}
// 保证别人能获取
public static Singleton getInstance(){
return INSTANCE;
}
}
2、懒汉式:
延迟加载就是调用get()方法时实例才是被创建(先不急着实例化出对象,等腰用的时候才给你创建出来,不着急,故又称为懒汉模式),常见的实现方法就是在get()方法中进行new实例。
懒汉式在多线程环境中时完全错误的,不能保证单例的状态。
public class Singleton2 {
// 初始化一个
private static Singleton2 INSTANCE = new Singleton2();
// 让别人不能new 将无参构造器私有化,保证别人不能实例化对象
private Singleton2(){
}
// 保证别人能获取
public static Singleton2 getInstance(){
if(INSTANCE == null){
INSTANCE = new Singleton2();
}
return INSTANCE;
}
}
3、静态内部类实现单例设计模式(比较推荐)
public class Singleton3 {
// 让别人不能new 将无参构造器私有化,保证别人不能实例化对象
private Singleton3(){
}
public static Singleton3 getInstance(){
return SingletonHolder.INSTANCE;
}
// 静态内部类会在第一次使用的时候加载一次,静态常量会在类加载后初始化一次。
public static class SingletonHolder{
private static final Singleton3 INSTANCE = new Singleton3();
}
}
五、匿名内部类
1、操作符:new
2、一个要实现的接口或者要继承的类,如果时匿名子类,需要继承或事项相应的父类或者接口;
3、一对括号,如果时匿名子类,与实例化普通类的语法类似,如果由构造参数,要带上构造参数,如果要实现一个接口,只需要一对括号即可;
4、一段被{}括起来的类声明主体;
5、末尾的“;”分号。
六、箭头函数
@FunctionalInterface
//函数式接口,接口里面只有一个函数方法,没有其他的东西,此接口存在只是为了传递方法。
public interface Function {
int plus(int i, int j);
}
public class Client1 {
public static void main(String[] args) {
Function function = (i, j) -> i+j; //这就是箭头函数
//如果函数体只有一句,就可以省略大括号和return关键字,如果时很多句,则还是需要用大括号和return
System.out.println(function.plus(1, 2));
}
}
六、值传递与引用传递
public static void changeString(String str){
str = "hello";
}
public static void main(String[] args) {
String str = "你好";
changeString(str);
System.out.println(str);
}
输出结果:
你好