java 代码块 万字详解

news2024/11/29 2:39:08
  • 概述 :

  • 特点 :

  • 格式 :

  • 情景 :

  • 细节 :

  • 演示 :

  • 英文 :

//=v=,新版编辑器无手动添加目录的功能,PC端阅读建议通过侧边栏进行目录跳转;移动端建议用PC端阅读。😂

一、概述 :

代码块,也称为初始化块属于类中的成员(即和属性,方法一样,是类的一部分)。代码块的形成如同方法一样,用花括号将一些代码包括起来。只不过相比方法来看,代码块只有"方法体"

二、特点 :

与方法相比,代码块没有返回值类型,没有方法名,也没有形参列表,是个名副其实的“三无方法”。代码块只有方法体,而且在调用时,不需要通过创建对象或是像使用类方法那样显式的调用;而是在加载包含代码块的类时,或者是在实例化该类对象时,自动的隐式调用

大家可以想象一下蛞蝓和蜗牛在形态上的区别。如下图所示:

如果说代码块就是蛞蝓[kuò yú],只有身体,没有框架;那么方法就相当于是蜗牛,既有框架来收容这个身体,身体本身的功能也正常。当然,就像蛞蝓和蜗牛都是害虫一样😂,代码块和方法也有自己的共同点,平时在方法中会写到的任意类型的语句,都可以根据需求写在代码块中。

三、格式 :

[修饰符] {

//方法体语句。(代码)

}

PS : (对格式的补充说明)

  1. 对于代码块前面的修饰符:可以不写!但你要是想写的话,只能使用static关键字来修饰

  1. 根据代码块是否有static修饰,可以将代码块分为非静态代码块(无static修饰)和静态代码块(添加了static修饰符)。(这是本质上的区别)

  1. 代码块最后的分号“;”可写可不写,但是建议大家写上,以示区分。

四、情景 :

说了这么一大堆,到底啥时候要用代码块呢?

前面我们说了,代码块并不能显式调用,而是在加载类或者实例化类时隐式地调用。其实,在我们后面的使用细节中就会说到——静态代码块是随着类的加载而被隐式调用,非静态代码块则是随着类的实例化而被隐式调用。大家先了解一下,因为要给大家举个例子,所以up先提一嘴,后面我们会细说

🆗,当多个构造器中有重复的代码片段时,我们就可以将这些重复的相同代码提取出来,放在一个非静态代码块中,这样每次创建一个该类对象,都会隐式地调用一次代码块,就不用你在每个构造器中都写一遍了,大大提高了代码的复用性。下面我们来举个例子 :

up以Rocket类(火箭类)为演示类,以Test类为测试类,我们在Rocket类中定义一个无参构造和两个带参构造,并使其都包含一段相同的代码段(模拟火箭发射的代码段)。老规矩,因为演示嘛,为了观感简洁,up将Test类写在了Rocket类的源文件下。Rocket类,Test类代码如下 :

package knowledge.polymorphism.code_block;

public class Rocket {
    public Rocket() {
        System.out.println("火箭发射倒计时:Come on !");
        System.out.println("10!");
        System.out.println("9!");
        System.out.println("8!");
        System.out.println("7!");
        System.out.println("6!");
        System.out.println("5!");
        System.out.println("4!");
        System.out.println("3!");
        System.out.println("2!");
        System.out.println("1!");
        System.out.println("0,发射!奥利给!");
        System.out.println("---------------------");
        System.out.println("火箭发射成功!(无参构造被掉用啦)");
    }
    public Rocket(String name) {
        System.out.println(name + "火箭发射倒计时:Come on !");
        System.out.println("10!");
        System.out.println("9!");
        System.out.println("8!");
        System.out.println("7!");
        System.out.println("6!");
        System.out.println("5!");
        System.out.println("4!");
        System.out.println("3!");
        System.out.println("2!");
        System.out.println("1!");
        System.out.println("0,发射!奥利给!");
        System.out.println("---------------------");
        System.out.println(name + "火箭发射成功!(第一个有参构造被调用啦)");
    }
    public Rocket(String name, String time) {
        System.out.println(name + "火箭发射倒计时:Come on !");
        System.out.println("10!");
        System.out.println("9!");
        System.out.println("8!");
        System.out.println("7!");
        System.out.println("6!");
        System.out.println("5!");
        System.out.println("4!");
        System.out.println("3!");
        System.out.println("2!");
        System.out.println("1!");
        System.out.println("0,发射!奥利给!");
        System.out.println("---------------------");
        System.out.println(name + "火箭在" + time + "发射成功!(第二个有参构造被调用啦)");
    }
}

class Test {
    public static void main(String[] args) {
        //利用无参构造创建火箭类对象
        Rocket rocket_1 = new Rocket();
        System.out.println("=============================================");

        //利用第一个有参构造创建火箭类对象
        Rocket rocket_2 = new Rocket("神舟99号");
        System.out.println("=============================================");

        //利用第二个有参构造创建火箭类对象
        Rocket rocket_3 = new Rocket("长征99号", "2077.10.1_8:34:50");
    }
}

运行效果如下GIF图 :

大家发现没有,三个构造器中都有表示火箭倒计时的代码,使我们的代码冗余度很高,看起来臃肿不堪,导致代码的复用性差。这时候我们可以将表示火箭倒计时的代码提取出来,放到一个非静态代码块中。这样不管你用哪个构造器来创建该类对象,只要你实例化了该类,每实例化一次都会默认隐式地调用非静态代码块中的内容。

更改后的代码如下所示 :

package knowledge.polymorphism.code_block;

public class Rocket {
    {
        System.out.println("火箭发射倒计时:Come on !");
        System.out.println("10!");
        System.out.println("9!");
        System.out.println("8!");
        System.out.println("7!");
        System.out.println("6!");
        System.out.println("5!");
        System.out.println("4!");
        System.out.println("3!");
        System.out.println("2!");
        System.out.println("1!");
        System.out.println("0,发射!奥利给!");
        System.out.println("---------------------");
    };
    public Rocket() {
        System.out.println("火箭发射成功!(无参构造被掉用啦)");
    }
    public Rocket(String name) {
        System.out.println(name + "火箭发射成功!(第一个有参构造被调用啦)");
    }
    public Rocket(String name, String time) {
        System.out.println(name + "火箭在" + time + "发射成功!(第二个有参构造被调用啦)");
    }
}

class Test {
    public static void main(String[] args) {
        //利用无参构造创建火箭类对象
        Rocket rocket_1 = new Rocket();
        System.out.println("=============================================");

        //利用第一个有参构造创建火箭类对象
        Rocket rocket_2 = new Rocket("神舟99号");
        System.out.println("=============================================");

        //利用第二个有参构造创建火箭类对象
        Rocket rocket_3 = new Rocket("长征99号", "2077.10.1_8:34:50");
    }
}

运行结果不变,如下GIF所示 :

五、细节 :

1.静态代码块作用是对整个类进行初始化工作,且随着类的被加载而被隐式地调用。由于一个类的字节码文件只会被加载一次,因此静态代码块最多只能被执行一次

而对于非静态代码块来说,每创建一个包含非静态代码块的类 (即每实例化一次该类),都会执行一次该类中的非静态代码块。注意:如果仅仅通过“类名.”的形式去调用类的静态成员(即类变量和类方法的使用),那么非静态代码块不会执行


2.关于类的加载类的加载时机

up在之前的java 反射基础 万字详解中已经讲过,大家有兴趣的话可以去看看,直接在目录中找到类加载部分即可。这里up给大家把截图放过来,如下 :


3.关于在创建对象时,静态成员、非静态成员,以及构造器在一个类中调用顺序 :

首先执行静态代码块(因为要加载类)和静态属性的初始化这两者的执行优先级相同,同级。但如果同时定义了多个静态代码块和多个静态属性的初始化语句,则按照定义的顺序来执行。(即谁在前头先执行谁)

其次执行非静态代码块和非静态属性的初始化;这两者的执行优先级也相同,同级。同理,若同时定义了多个非静态代码块和多个非静态属性的初始化语句,则按照定义的先后顺序来执行。

最后执行构造器初始化


4.为什么是上面第三点提到的这个顺序?

我们知道,构造器的最前面默认隐含一条super(); 语句;其实,在super();语句后面,还隐含了调用非静态代码块的语句。所以,这就能解释为什么是第三点注意提到的顺序了——静态成员(静态代码块,静态属性的初始化)在类加载器加载该类时就已经执行完毕了,所以它们是第一优先级;而由于构造器中隐含了调用非静态代码块的语句,因此,必须先执行完毕非静态代码块,才能继续执行构造器。


5.在继承关系的基础上,创建子类对象时,静态成员、非静态成员,以及构造器在子父类中调用顺序:(多层继承也适用)

首先,执行父类的静态代码块和静态属性初始化语句。(若同时定义了多个,因为优先级同级,按照定义的先后顺序执行)

其次,执行子类的静态代码块和静态属性初始化语句。(同上)

接着,执行父类的非静态代码块和非静态属性初始化。(同上)

接着,执行父类构造器。

接着,执行子类的非静态代码块和非静态属性初始化。(同上)

最后,执行子类构造器。

为什么?

在上文”类的加载时机“中我们谈到——初始化类的子类时,要先加载父类,而类的静态代码块和静态属性的初始化是随着类的加载而执行完毕的。因此,当创建子类对象时,第一步是执行父类的静态代码块和静态属性初始化;第二步才是执行子类的静态代码块和静态属性初始化。当子类和父类都加载成功后,jvm要根据你创建子类对象时传入的参数去找子类中对应的构造器;但是别忘了——之前我们讲到继承关系时我们说过,继承关系中,对象的初始化顺序为 : 先初始化父类内容,后初始化子类内容所以会先通过子类的super语句,来到父类的构造器,而父类构造器又隐含了调用父类非静态代码块的语句,而且,我们在创建对象的内存图解中也讲过,对象属性的初始化有三步:默认初始化,显式初始化,构造器初始化。因此,第三步是执行父类的非静态代码块和非静态属性初始化;第四步才是执行父类的构造器。父类内容初始化完成后,返回子类构造器中,子类构造器也隐含了调用子类非静态代码块的语句,因此第五步是执行子类的非静态代码块和非静态属性初始化,第六步才是执行子类构造器。至此,一个子类对象创建完毕。


6.在讲到static关键字时我们说过,静态成员只能调用静态成员(类变量和类方法),而非静态成员既能调用静态成员,也能调用非静态成员。文章开篇我们就说了,代码块不也是类的成员么?因此,静态代码块只能调用静态成员(类变量,类方法),而非静态代码块可以调用任意成员

六、演示 :

1.演示细节1 :

up以Cat类为演示类,以TestDetial_1作为第一个测试类。我们在Cat类中定义一个静态代码块和一个非静态代码块。通过在测试类中创建多个Cat类对象,来观察两种代码块的执行次数各有什么特点。

Cat类,TestDetail_1类代码如下 :

package knowledge.polymorphism.code_block.chinese.detail_1;
/*
    //细节1 :
            静态代码块的作用是对整个类进行初始化工作,且随着类的被加载而被隐式地调用。
        由于一个类的字节码文件只会被加载一次,因此静态代码块也最多只能被执行一次。
            而对于非静态代码块来说,每创建一个包含非静态代码块的类 (即每实例化一次该类),
        都会执行一次该类中的非静态代码块。注意:如果仅仅通过“类名.”的形式去调用
        类的静态成员(即类变量和类方法的使用),那么非静态代码块不会执行。
 */
public class Cat {
    {
        System.out.println("这是Cat类中的非静态代码块捏🤗");
        System.out.println("非静态代码块,随着类的实例化而执行,每实例化一次类就执行一次");
        System.out.println("===============================");
    };

    static {
        System.out.println("这是Cat类中的静态代码块捏🤗");
        System.out.println("静态代码块,随着类的加载而执行,仅执行一次");
        System.out.println("===============================");
    };
    public static String name = "猫";
    public static void eat() {
        System.out.println("🐱喜欢吃🥩");
    }

    public Cat() {}
}
class TestDetail_1 {
    public static void main(String[] args) {
        //创建Cat类对象
        Cat cat_0 = new Cat();
        Cat cat_1 = new Cat();
        Cat cat_2 = new Cat();
    }
}

运行结果 :


2.演示细节2 :

细节2没啥演示的吧😂,基本都继承那块儿的。

这样,给大家演示一下调用静态成员时类的加载情况吧,如下 :

up以Dog类为演示类,以TestDetail_2类为第二个测试类。在Dog类中定义一个静态的dog()方法。然后在测试类中通过类名来调用这个类方法。观察该类的静态代码块是否执行。

Dog类,TestDetail_2类代码如下 :

package knowledge.polymorphism.code_block.chinese.detail_2;

public class Dog {
    static {
        System.out.println("这是Dog类的静态代码块,如果Dog类被加载,那么这句话一定输出!");
        System.out.println("------------------------------------");
    };
    //定义Dog类的静态方法(类方法)
    public static void dog() {
        System.out.println("我虽然不是人,但你是真的🐕。");
    }
}

class TestDetail_2 {
    public static void main(String[] args) {
        //以类名的形式调用Dog类中的类方法
        Dog.dog();
    }
}

运行结果 :


3.演示细节3 :

up以Fish类为演示类,以TestDetail_3类为第三个测试类。在Fish类中定义静态代码块静态属性(使用静态方法给静态属性赋初值)非静态代码块非静态属性(通过非静态方法给非静态属性赋初值),以及一个Fish类的空参构造在每个成员中均打印出提示信息。在测试类中创建Fish类对象,观察Fish类中各个成员的执行顺序。

Fish类,TestDetail_3类代码如下 :

package knowledge.polymorphism.code_block.chinese.detail_3;
/*
    //细节3 :
        ①首先执行静态代码块(因为要加载类)和静态属性的初始化;这两者的执行优先级相同,同级。
        但如果同时定义了多个静态代码块和多个静态属性的初始化语句,
        则按照定义的顺序来执行。(即谁在前头先执行谁)
        ②其次执行非静态代码块和非静态属性的初始化;这两者的执行优先级也相同,同级。
        同理,若同时定义了多个非静态代码块和多个非静态属性的初始化语句,
        则按照定义的先后顺序来执行。
        ③最后执行构造器初始化。
*/
public class Fish {
    //Fish类的代码块
    {
        System.out.println("这是Fish类的非静态代码块");
        System.out.println("非静态代码块的执行处于第二优先级,因此这句话是第二阶段输出");
    };
    static {
        System.out.println("这是Fish类的静态代码块");
        System.out.println("静态代码块的优先级是最高的!所以这句话必须第一阶段输出。");
    };

    //Fish类构造器
    public Fish() {
        System.out.println("最后输出的就是Fish类的构造器🌶!这是第三阶段输出。");
    }

    //Fish类静态属性及其初始化
    public static String name = getName();
    public static String getName() {
        System.out.println("静态属性的初始化与静态代码块的执行为相同优先级。所以也是第一阶段输出");
        System.out.println("只不过此处静态属性定义的位置靠后一点点,所以这句话输出稍微靠后。");
        System.out.println("------------------------------------------------");
        return "鱼";
    }

    //Fish类非静态属性及其初始化
    public String hobby = getHobby();
    public String getHobby() {
        System.out.println("非静态属性的初始化,和非静态代码块相同优先级。");
        System.out.println("只不过由定义的先后顺序来看,这句话要在非静态代码块之后才能输出。");
        System.out.println("------------------------------------------------");
        return "鱼能有啥爱好😅,喜欢游泳🏊‍?";
    }
}

class TestDetail_3 {
    public static void main(String[] args) {
        //创建Fish类对象,看看各个阶段的输出内容分别是个啥。
        Fish fish = new Fish();
        System.out.println(fish.hobby);
    }
}

运行结果 :


4.演示细节4 :

up以Fruit类为父类,子类Apple类继承了Fruit类;以TestDetail_4类为第四个测试类。在子父类中均定义一个无参构造,和一个非静态代码块。通过控制台打印出的信息观察执行规律。

Fruit类,Apple类,TestDetail_4类代码如下 :

package knowledge.polymorphism.code_block.chinese.detail_4;
/*
    //细节4 :
        构造器的最前面默认隐含一条super(); 语句;
        其实,在super();语句后面,还隐含了调用非静态代码块的语句。
 */
public class Fruit {
    {
        System.out.println("Fruit类的非静态代码块。");
    };
    public Fruit() {
        //super(); 父类构造器中其实也隐含了supper语句,只不过顶层父类Object类中不会输出内容。
        //supper语句之后隐含了调用本类非静态代码块的语句。
        System.out.println("这是父类构造器");
    }
}
class Apple extends Fruit {
    {
        System.out.println("Apple类的非静态代码块。");
    };
    public Apple() {
        //super();
        //实质这里还隐含了调用本类非静态代码块的语句。
        System.out.println("这是子类构造器。");
    }
}

class TestDetail_4 {
    public static void main(String[] args) {
        Apple apple = new Apple();
    }
}

运行结果 :

我们之前说过,对于非静态代码块,每实例化一次类就执行一次。

通过输出结果可以看到,尽管我们创建的是子类对象,但因为super语句调用父类构造器,而父类构造器中隐含调用非静态代码块的语句。因此最后输出的内容中,会先输出父类的非静态代码块。


5.演示细节5 :

up以Fruit类(水果类)为父类,子类Apple类(苹果类)继承Fruit类,子类的子类HongFuShi类(红富士类)继承Apple类;以TestDetail_5为第五个测试类。

在三个类中均定义静态代码块,静态属性;非静态代码块,非静态属性;以及构造器。并在每个成员中给出提示信息。在测试类中创建红富士类对象,根据控制台打印出的提示信息来

Fruit类,Apple类,HongFuShi类代码如下 :

package knowledge.polymorphism.code_block.chinese.detail_5;

public class Fruit {            //父类 : 水果类
    //Fruit类静态属性及其初始化
    private static String name = getName();
    public static String getName() {
        System.out.println("1.这是父类Fruit类的静态方法,用于初始化父类的静态属性。");
        return "水果";
    }

    //Fruit类的非静态属性及其初始化
    private String color = getColor();
    public String getColor() {
        System.out.println("7.这是父类Fruit类的非静态方法,用于初始化父类的非静态属性。");
        return "水果的颜色";
    }

    //Fruit类构造器(空参)
    public Fruit() {
        System.out.println("9.这是父类Fruit类的空参构造。");
        System.out.println("-------------------------------------");
    }

    //Fruit类的静态代码块和非静态代码块
    static {
        System.out.println("2.这是Fruit类的静态代码块");
    };
    {
        System.out.println("8.这是Fruit类的非静态代码块");
    };
}
class Apple extends Fruit {         //子类 : 苹果类
    //Apple类静态属性及其初始化
    private static String name = getName();
    public static String getName() {
        System.out.println("3.这是子类Apple类的静态方法,用于初始化子类的静态属性。");
        return "苹果";
    }

    //Apple类的非静态属性及其初始化
    private String apple_color = getApple_color();
    public String getApple_color() {
        System.out.println("10.这是子类Apple类的非静态方法,用于初始化子类的非静态属性。");
        return "苹果的颜色";
    }

    //Apple类构造器(空参)
    public Apple() {
        System.out.println("12.这是子类Apple类的空参构造。");
        System.out.println("-------------------------------------");
    }

    //Apple类的静态代码块和非静态代码块
    static {
        System.out.println("4.这是Apple类的静态代码块");
    };
    {
        System.out.println("11.这是Apple类的非静态代码块");
    };
}
class HongFuShi extends Apple {         //子类的子类 : 红富士类
    //HongFuShi类静态属性及其初始化
    private static String name = getName();
    public static String getName() {
        System.out.println("5.这是最底层子类HongFuShi类的静态方法,用于初始化最底层子类的静态属性。");
        return "红富士";
    }

    //HongFuShi类的非静态属性及其初始化
    private String HongFuShi_color = getHongFuShi_color();
    public String getHongFuShi_color() {
        System.out.println("13.这是最底层子类HongFuShi类的非静态方法,用于初始化最底层子类的非静态属性。");
        return "红色";
    }

    //HongFuShi类构造器(空参)
    public HongFuShi() {
        System.out.println("15.这是最底层子类HongFuShi类的空参构造。");
        System.out.println("-------------------------------------");
    }

    //HongFuShi类的静态代码块和非静态代码块
    static {
        System.out.println("6.这是HongFuShi类的静态代码块");
        System.out.println("-------------------------------------------");
    };
    {
        System.out.println("14.这是HongFuShi类的非静态代码块");
    };
}
class TestDetail_5 {
    public static void main(String[] args) {
        //创建一个红富士类对象。
        HongFuShi hongFuShi = new HongFuShi();
    }
}

运行结果 :

大家一开始理解起来有点难度是正常的。大家一定要记住,每个构造器的第一行默认隐含super语句,并且在super语句之后还默认隐含了调用非静态代码块的语句。可以说,想要完全理解这一块知识点,需要大家对Java 继承有不错的掌握程度。

这里up再给大家捋一捋,如下(全文背诵) :

首先,你要创建最底层子类红富士类的对象,肯定要先将该类的字节码文件加载到方法区,但是加载时jvm发现红富士类继承了苹果类,因此必须先加载苹果类的字节码文件;但是加载时jvm又发现苹果类继承的水果类,因此必须最先加载水果类的字节码文件

好嘞,我们知道,静态代码块静态属性的初始化是随着类的加载而执行完毕的。因此,在加载水果类时,会执行水果类的静态代码块和静态属性初始化。水果类加载完毕后,就要返回去加载它的子类苹果类,因此要顺势执行苹果类中的静态代码块和静态属性初始化。等爸爸和爷爷完事儿后,这才轮到孙子,红富士类也不敢耽搁,兢兢业业赶紧加载,jvm也顺势执行红富士类中的静态代码块和静态属性初始化。到此,这三个类都加载完毕。

这时,jvm会根据你创建红富士类对象时传入的形参列表,去红富士类中找对应的构造器。但是,刚找到构造器准备执行呢,构造器第一行埋伏着默认的super语句,立马被迫来到了苹果类;没想到丫的苹果类也隐含默认语句super,立马又被迫来到水果类;继承机制要求我们要先将父类水果类进行初始化;然而水果类的构造器第一行也有super语句,但是水果类的父类就是顶层父类Object类了,就不多说了。除去super语句外,水果类的构造器中还隐含了调用水果类非静态代码块的语句,且水果类中非静态属性的构造器初始化之前是显式初始化,因此下一步是执行水果类的非静态代码块和非静态属性初始化。这些都🆗后,才能执行水果类的构造器。好不容易算是把父类初始化完毕,这算是苹果类的super语句结束了。

接着又返回子类苹果类的构造器中,super语句之后又隐藏了调用苹果类的非静态代码块的语句,且苹果类非静态属性的构造器初始化之前,要进行显式初始化,因此下一步是执行苹果类的非静态代码块和非静态属性初始化。这些都🆗后,才能执行苹果类的构造器。这算是最底层子类红富士类的super语句结束了。(与同理)

接着又返回最底层子类红富士类的构造器中,super语句之后又隐藏了调用红富士类的非静态代码块的语句,且红富士类非静态属性的构造器初始化之前,要进行显式初始化,因此下一步是执行红富士类的非静态代码块和非静态属性初始化。这些都🆗后,才能执行红富士类的构造器,初始化红富士类对象。至此,结束(与同理)


6.演示细节6 :

其实细节6也没什么好演示的,都是老生常谈的问题😂,和之前讲到static修饰方法时一个道理。

up以Student类作为演示类,以TestDetail_6作为第六个测试类。在Student类中定义静态属性name和非静态属性age;再定义静态方法getName() 和非静态方法getAge() ,并分别定义静态代码块和非静态代码块,去调用这些成员。在测试类创建Student类对象并查看输出结果。

Student类,TestDetail_6类代码如下 :

package knowledge.polymorphism.code_block.chinese.detail_6;

public class Student {
    private static String name = "Cyan";
    private int age = 20;

    public static String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }

    {
        System.out.println(name);                   //非静态代码块——可以调用静态成员
        System.out.println(age);
        System.out.println("name = " + getName());
        System.out.println("age = " + getAge());    //非静态代码块——也可以调用非静态成员
    };
    static {
        System.out.println(name);                   //静态代码块——只能调用静态成员
        //System.out.println(age);     //这么写会报错。
        System.out.println("name = " + getName());
        //System.out.println("age = " + getAge());  //静态代码块——不可以调用非静态成员
        System.out.println("-----------------------------------");
    };
}
class TestDetail_6 {
    public static void main(String[] args) {
        Student student = new Student();
    }
}

运行结果 :

如果我们在Student类的静态代码块中调用非静态成员变量age或者是非静态成员方法getAge(),IDEA就会报错,如下图所示 :

七、英文:

其实up是先发的英文版本😂,但没关系。英文版本适合英文六级及以上水平的小伙伴儿们阅读。up的英文版本都是拿英文重新描述的,所举案例和描述思想都会不同;而且up如果有写英文讲解java 的想法时,一般都是先写英文版本,再写中文版本;不会存在单纯的翻译这一“拙劣行径”,大家放心!

好滴,up把英文版本的代码块(Code Block) 详解链接给大家放下面了,感谢阅读!

https://blog.csdn.net/TYRA9/article/details/128992057?spm=1001.2014.3001.5501

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/344884.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3 如何实现一个带遮罩的 dialog 对话框

theme: mk-cute 开启掘金成长之旅!这是我参与「掘金日新计划 12 月更文挑战」的第7天,点击查看活动详情 前言: 今天在项目中遇到了很多很多需要弹出一个对话框的场景,由于之前全都是通过 v-if 来控制这个组件的显示与否&#x…

【python游戏】让我们一起制作地球联邦阵营的战机,保护希望水晶,为人类的希望而战。

前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 随着人类太空科技的飞速发展,希望水晶被越来越多的科学家当做核心能源来开发使用。 人类社会也因为水晶资源的争夺,开始逐渐分化成两派。 留在地球的普通人成立地球联邦,移居卫星的新人…

我对平衡二叉树的理解(比喻的方式)

传销是一种恶性的行销方式,主要手段就是激励其中的成员拉人头。 有个奇怪的传销组织,他们的传销规则是这样的: 每个人最多可以带着2人进该组织,其中1个年纪比自己大,另1个年纪比自己小新人都是由创始人找到。假如年纪…

中文关键词提取算法

中文关键词提取算法 如何提取query或者文档的关键词? 一般有两种解决思路: 有监督方法,把关键词提取问题当做分类问题,文本分词后标记各词的重要性打分,然后挑出重要的topK个词;无监督方法,使…

likeshop单商户SaaS版V1.8.2说明!

likeshop单商户SaaS版V1.8.2主要更新如下: 新增 前端登录引导用户填写头像昵称 PC端—注册页面显示服务协议和隐私政策 PC端—首次进入商城弹出协议提示 PC端—结算页新增门店自提的配送方式 后台—PC端菜单导航栏的跳转链接支持添加自定义链接 ​​ ​​ ​ 优…

2022年“网络安全”赛项宜昌市选拔赛 任务书

2022年“网络安全”赛项宜昌市选拔赛 任务书 任务书 一、竞赛时间 共计3小时。 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段单兵模式系统渗透测试 任务一 数据库服务渗透测试 任务二 Wireshark数据包分析 任务三 Windows操作系统渗透测试 任务四 系统漏…

腾讯云企业网盘正式入驻数字工具箱

腾讯技术公益继腾讯电子签等入驻后,上线近半年的腾讯技术公益数字工具箱再次迎来新成员——腾讯云企业网盘,现已正式接受公益机构申请公益权益。腾讯云企业网盘(https://pan.tencent.com)是由腾讯云推出的一款安全、高效、开放的企…

python+flask开发mock服务

目录 什么是mock? 什么时候需要用到mock? 如何实现? pythonflask自定义mock服务的步骤 一、环境搭建 1、安装flask插件 2、验证插件 二、mock案例 1、模拟 返回结果 2、模拟 异常响应状态码 3、模拟登录,从jmeter中获取…

Kafka 消费者

与生产者对应的是消费者,应用程序可以通过 KafkaConsumer 来订阅主题,并从订阅主题中拉取消息。 消息者与消费组 消费者(Consumer)负责订阅 Kafka 中的主题(Topic),并且从订阅的主题上拉取消息…

低代码开发平台|制造管理-生产过程管理搭建指南

1、简介1.1、案例简介本文将介绍,如何搭建制造管理-生产过程。1.2、应用场景先填充工序信息,再设置工艺路线对应的工序;工序信息及工艺路线列表报表展示的是所有工序、工艺路线信息,可进行新增对应数据的操作。2、设置方法2.1、表…

女生做大数据有发展前景吗?

当前大数据发展前景非常不错,且大数据领域对于人才类型的需求比较多元化,女生学习大数据也会有比较多的工作机会。大数据是一个交叉学科涉及到的知识量比较大学习有一定的难度,女生比较适合大数据采集和大数据分析方向的工作岗位。 大数据采…

【沁恒WCH CH32V307V-R1与Arduino的串口通讯】

【沁恒WCH CH32V307V-R1的单线半双工模式串口通讯】1. 前言2. 软件配置2.1 安装MounRiver Studio3. UASRT项目测试3.1 打开UASRT工程3.2 CH307串口发送数据到Arduino实验3.3 CH307串口接收数据Arduino实验5. 小结1. 前言 本例演示了采用CH307串口3与Arduino软串口收发通信&…

Python的深、浅拷贝到底是怎么回事?一篇解决问题

嗨害大家好鸭!我是小熊猫~ 一、赋值 Python中, 对象的赋值都是进行对象引用(内存地址)传递, 赋值(), 就是创建了对象的一个新的引用, 修改其中任意一个变量都会影响到另一个 will …

第七届蓝桥杯省赛——5分小组

题目:9名运动员参加比赛,需要分3组进行预赛。有哪些分组的方案呢?我们标记运动员为 A,B,C,... I下面的程序列出了所有的分组方法。该程序的正常输出为:ABC DEF GHIABC DEG FHIABC DEH FGIABC DEI FGHABC DFG EHIABC DFH EGIABC DF…

VFIO软件依赖——VFIO协议

文章目录背景PCI设备模拟PCI设备抽象VFIO协议实验Q&A背景 在虚拟化应用场景中,虚拟机想要在访问PCI设备时达到IO性能最优,最直接的方法就是将物理设备暴露给虚拟机,虚拟机对设备的访问不经过任何中间层的转换,没有虚拟化的损…

2023年小鹏新能源汽车核心部件解密

小鹏主要硬件清单(G9车型) 感知层 从硬件上看,G9搭载两颗NVIDIA DRIVE Orin 智能辅助驾驶芯片,算力达到 508 TOPS。此外,全车周边31 个感知元器件,(800万双目、4个300万侧前侧后、4个130万环视、1个170万后视、1个100万DMS)、12个超声波雷达、5个毫米波雷达、2个速…

TeamFiltration:一款针对O365 AAD账号安全的测试框架

关于TeamFiltration TeamFiltration是一款针对O365 AAD账号安全的跨平台安全测试框架,在该工具的帮助下,广大研究人员可以轻松对O365 AAD账号进行枚举、喷射、过滤和后门植入等操作。TeamFiltering与CrackMapExec非常相似,它可以创建并维护一…

四大垃圾回收算法七大垃圾回收器

JVM的运行时内存也叫做JVM堆,从GC的角度可以将JVM分为新生代、老年代和永久代。其中新生代默认占1/3堆内存空间,老年代默认占2/3堆内存空间,永久代占非常少的对内存空间。新生代又分为Eden区、SurvivorFrom区和SurvivorTo区, Eden…

Python基础知识复习以及第三方库openxel的初步使用

目录文件python文件打开函数Python中的split函数详细解释List对象list添加元素的三种方法删除元素反转Python第三方库openxel的初步使用excel文件对象open操作excel入门文件 python文件打开函数 语法:open(file, mode ‘r’, buffering-1, encodingNon…

【高性价比】初学者入门吉他值得推荐购买的民谣单板吉他品牌—VEAZEN费森吉他

“在未知的世界里,我们是一群不疲不倦的行者,执念于真善美,热衷于事物的极致。我们抽丝剥茧,不断地打败自己,超越自己,我们无所畏惧终将成为巨人。”这是VEAZEN吉他官网首页上很明显的一段话,也…