Java 内部类详解

目录

一. 前言

二. Java 类的创建要求

三. Java 内部类分类

3.1. 成员内部类

3.1.1. 特点

3.1.2. 语法

3.1.3. 代码示例

3.1.4. 代码测试

3.1.5. 关于 this 的注意事项

3.1.6. 小结

3.2. 局部内部类

3.2.1. 特点

3.2.2. 语法

3.2.3. 代码示例

3.2.4. 代码测试

3.2.5. Effectively final 特性

3.3. 匿名内部类

3.3.1. 特点

3.3.2. 语法

3.3.3. 代码示例

3.3.4. 代码测试

3.4. 静态内部类

3.4.1. 特点

3.4.2. 语法

3.4.3. 代码示例

3.4.4. 代码测试

3.4.5. 小结

四. 总结


一. 前言

    在 Java 中,我们通常是把不同的类创建在不同的包里面,对于同一个包里的类来说,它们都是同一层次的。但其实还有另一种情况,有些类可以被定义在另一个类的内部,我们把在一个类里面定义的类称为内部类(InnerClass)或嵌套类,把外面定义的类称为外部类(OutClass)或宿主类。

    也就是说,在类的内部既可以定义成员变量和方法,也可以定义其他的类。定义内部类的常见格式如下:

public class Outer { // 外部类class Inner { // 内部类// 方法和属性}
}

上面的代码中,Outer 是普通的外部类,Inner就是内部类。它与普通外部类最大的不同,在于其 实例对象不能单独存在,必须依附于一个外部类的实例对象。

    内部类可以很好地实现隐藏,一般的非内部类是不允许有 private 与 protected 权限的,但内部类却可以,而且内部类还拥有外部类中所有元素的访问权限。总之,对内部类的很多访问规则都可以参考变量和方法。

    但是要注意,虽然我们使用内部类可以使程序结构变得更加紧凑,但却在一定程度上破坏了面向对象的思想。

二. Java 类的创建要求

我们在创建定义Java类时,应该遵循如下要求:

  • 一个 Java 文件中可以编写多个类,但只能有一个类使用 public 关键词进行修饰,这称之为主类;
  • 主类名必须与文件名一致,在开发中,应尽量只在一个 Java 文件中编写一个类;
  • 外部类只有两种访问级别:public 和 default(默认);内部类则有 4 种访问级别:public、protected、 private 和 default(默认);
  • 在外部类中,可以直接通过内部类的类名来访问内部类;
  • 在外部类以外的其他类中,需要通过内部类的完整类名来访问内部类;
  • 内部类与外部类不能重名。

三. Java 内部类分类

    Java 中的内部类可以分为如下几种类型:成员内部类、静态内部类、局部内部类、匿名内部类。虽然大多数时候,内部类用得并不多,但我们也有必要了解它们是如何具体使用的。

3.1. 成员内部类

成员内部类就是指没有被 static 修饰的内部类,也可以称为非静态内部类。

3.1.1. 特点

成员内部类具有如下特点:

  • 在 JDK16 版本以前,成员内部类中只能定义非静态的属性和方法,除非同时使用 final 和static 进行修饰;
  • 在 JDK16 及之后的版本中,成员内部类中也可以定义静态的属性和方法;
  • 成员内部类可以访问外部类的所有成员,包括私有和静态的成员,即使是多层嵌套时也如此;
  • 外部类不能直接访问内部类的成员,必须通过内部类的实例对象访问;
  • 在外部类的静态方法和外部类以外的其他类中,必须通过外部类的实例创建内部类的实例对象;
  • 外部类的实例与内部类实例是一对多的关系,即一个内部类实例只对应一个外部类实例,但一个外部类实例则可以对应多个内部类实例。

3.1.2. 语法

如果是在外部类中,创建成员内部类对象的基本语法格式如下:

// 内部类 对象名 = new 内部类();
Inner inner = new Inner();

如果是在外部的其他类中,或者是在外部类的静态方法中,创建成员内部类对象的基本语法格式如下:

// 内部类 对象名 = new 外部类().new 内部类();
Inner inner = new Outer().new Inner();

3.1.3. 代码示例

/*** 成员内部类*/
public class OuterClass {// 外部类的非静态成员String name = "流华追梦";private String hobby = "写代码";static int age = 28;// 非静态方法public void show() {// 这里的 this 是指 OuterClass 对象System.out.println("show 方法,name = " + this.name);// 如果是在外部类里面创建内部类的对象,就不需要创建外部类实例,可以直接 new 内部类();// InnerClass inner = new InnerClass();}// 定义一个成员内部类public class InnerClass {// 也可以定义私有属性private int a = 10;// 在 JDK16 版本以前,成员内部类中不能定义静态变量;在 JDK16 及之后的版本中,成员内部类中可以定义静态变量。static int b = 20;// 非静态方法public void testInner1() {// 这里的 this 是指 InnerClass 内部类对象System.out.println("成员内部类的成员变量:" + this.a);// 外部类.this.属性或方法,这个 this 是外部类对象System.out.println("外部类的成员变量:" + OuterClass.this.name);// 内部类中可以访问外部类的私有成员和静态成员System.out.println("外部类的私有成员变量:" + hobby);System.out.println("外部类的静态变量:" + age);}// 在 JDK16 版本以前,成员内部类中不能定义静态方法;在 JDK16 及之后的版本中,成员内部类中可以定义静态方法。public static void testInner2() {System.out.println("调用成员内部类的静态变量:" + b);System.out.println("调用外部类的静态变量:" + age);// 在静态方法中创建内部类对象,也要通过 内部类 对象名 = new 外部类().new 内部类(); 的格式InnerClass innerClass = new OuterClass().new InnerClass();}}
}

我们要注意,在 JDK16 版本以前,成员内部类中不能定义静态属性和方法;但在 JDK16 及之后的版本中,成员内部类中可以定义静态的属性和方法。并且我们要搞清楚在不同的位置上,创建内部类对象的方式,以及 this 的具体含义。

3.1.4. 代码测试

我们在外部的其他类中,要想创建出一个成员内部类的对象,需要通过如下形式:

// 内部类 对象名 = new 外部类().new 内部类();
Inner inner = new Outer().new Inner();
public class InnerClassTest {public static void main(String[] args) {// 在外部的其他类中,不能直接创建内部类对象,否则:// No enclosing instance of type OuterClass is accessible.// Must qualify the allocation with an enclosing instance of type OuterClass// (e.g. x.new A() where x is an instance of OuterClass).// InnerClass inner = new InnerClass();// 在外部的其他类中创建内部类对象,需要通过如下格式:// 内部类 对象名 = new 外部类().new 内部类();// InnerClass inner = new OuterClass().new InnerClass();// 也可以拆分成如下格式:OuterClass outer = new OuterClass();InnerClass inner = outer.new InnerClass();inner.testInner1();InnerClass.testInner2();}
}

3.1.5. 关于 this 的注意事项

在内部类中,关于 this,我们需要注意以下两点:

  • 如果同时存在外部类和内部类,那么 this 在哪个类中使用,this 就代表哪个类的对象;
  • 如果内部类想要通过 this 来调用外部类的属性和方法,需要使用 外部类名.this.属性或者方法名。

3.1.6. 小结

    学习到这里,你可能会被内部类与外部类之间的调用访问关系整蒙圈,所以给大家梳理了一下访问方式:
1. 成员内部类 访问 外部类的成员(属性、方法),可以【直接访问使用】;
2. 外部类 访问 成员内部类,需要【直接创建内部类对象后再访问】,即 new InnerClass();
3. 外部的其他类 访问 成员内部类,需要【创建外部类对象,再创建内部类对象后访问】,即 InnerClass inner = new OuterClass().new InnerClass();

3.2. 局部内部类

局部内部类是指在方法中定义的内部类。

3.2.1. 特点

局部内部类具有如下特点:

  • 局部内部类只能在方法中定义和创建对象,也只在当前方法中有效;
  • 局部内部类中可以访问外部类的所有成员;
  • 局部内部类与局部变量一样,不能使用访问控制修饰符(public、private、protected)和 static 修饰符;
  • 在 JDK7 版本中,如果局部变量是在局部内部类中使用,必须显式地加上 final 关键字;在 JDK8 及之后版本中,会默认添加 final 关键字;
  • 局部内部类只能访问当前方法中 final 类型的参数与变量。如果方法中的成员与外部类的成员同名,可以使用 <OuterClassName>.this.<MemberName> 的形式访问外部类成员;
  • 局部内部类中还可以包含内部类,但这些内部类也不能使用访问控制修饰符(public、private 、protected)和 static 修饰符;
  • 局部变量在方法执行结束后会被销毁,而局部内部类的对象会等到内存回收机制进行销毁。如果是局部内部类里的常量,该常量会被存放在常量池中。

3.2.2. 语法

创建局部内部类对象的基本语法格式如下:

public class PartClass {public void methodA() {// 在方法中定义的内部类,就是局部内部类class Inner {// 属性// 方法}}
}

3.2.3. 代码示例

public class PartOuterClass {// 类的成员变量String name = "流华追梦";private int age = 28;static String hobby = "Java";public void show() {// 局部变量// JDK7 之前,匿名内部类和局部内部类中访问外部的局部变量时,该变量需要明确地带有 final 修饰符// final int num = 10;// Effectively final 特性int num = 10;// 局部内部类,类似于是方法中的局部对象class PartInnerClass {// 内部可以正常定义方法public void testInner1() {// 访问外部类的非静态成员,可以使用 OuterClass.this.成员 的格式,也可以直接访问// System.out.println("外部类的成员变量:" + name);System.out.println("外部类的成员变量:" + PartOuterClass.this.name);System.out.println("外部类私有的成员变量:" + age);System.out.println("外部类的静态变量:" + hobby);// 局部内部类,可以直接访问方法中的局部变量System.out.println("访问局部变量:" + num);}// 在 JDK16 及之后的版本中,也可以定义静态属性和静态方法,但之前的 JDK 版本则不行static int b = 10;public static void testInner2() {System.out.println("外部类的静态变量,hobby = " + hobby + ",b = " + b);}}// 创建局部内部类对象PartInnerClass inner = new PartInnerClass();inner.testInner1();// 在当前类中,局部内部类可以直接访问静态成员PartInnerClass.testInner2();}
}

在 JDK7 之前,匿名内部类和局部内部类中访问外部的局部变量时,该变量需要明确地带有 final 修饰符。但从 JDK8 之后,我们可以不带 final 修饰符,而是由系统默认添加了。

3.2.4. 代码测试

接下来我们对上面的示例进行测试:

public class PartInnerClassTest {public static void main(String[] args) {// 创建外部类对象,调用方法,执行局部内部类PartOuterClass outer = new PartOuterClass();outer.show();}
}

3.2.5. Effectively final 特性

    一般情况下,Java 中的局部内部类和匿名内部类访问局部变量时,该变量必须由 final 修饰,以保证内部类和外部类的数据一致性。但从 Java8 开始,我们可以不加 final 修饰符,而是由系统默认添加,当然这在 Java8 以前是不允许的。Java 将这个新的特性称为 Effectively(有效的、实际的)final 功能。

另外在 lambda 表达式中,使用局部变量时也要求该变量必须是 final 修饰的,所以 effectively final特性在 lambda 表达式的上下文中非常有用。

其实 effectively final 特性,只是让我们不用显式地把变量声明为 final 修饰的,它给我们自动添加了 final 修饰词,但并没有取消 final,主要是减少了一点不必要的操作,给开发节省了点时间。

3.3. 匿名内部类

    匿名内部类就是指没有类名的内部类,必须在创建时使用 new 语句来声明。匿名内部类不能在Outer Class 外部类中定义,而是要在某个方法的内部,通过匿名类(Anonymous Class)的形式来定义。匿名内部类本身就是一个对象。

    通常情况下,如果一个方法的参数是接口类型,且该接口只需要实现一次,那么我们就可以通过匿名内部类的形式来进行定义。另外如果该接口的实现每次都不同,也可以使用匿名内部类的形式进行定义。我们也可以把这种定义形式叫做“接口回调”。匿名内部类的代码格式使得代码更加简洁、紧凑,模块化程度也更高。

3.3.1. 特点

匿名内部类具有如下特点:

  • 匿名内部类本身就是一个对象;
  • 一般在匿名内部类中不会定义属性和方法,因为没有意义;
  • 匿名内部类的父类一般都是抽象类或者是接口;
  • 匿名内部类和局部内部类一样,可以访问外部类的所有成员;
  • 如果匿名内部类位于方法中,则该类只能访问方法中 final 类型的局部变量和参数;
  • 匿名内部类中允许使用非静态代码块对成员进行初始化操作;
  • 匿名内部类的非静态代码块会在父类的构造方法之后被执行。

3.3.2. 语法

通常匿名内部类有两种实现方式:

  • 继承一个类,重写其方法;
  • 实现一个或多个接口,并实现其方法。

创建匿名内部类对象的基本语法格式如下:

new <类或接口>() {// 重写类或接口的方法
}// 典型示例:
new Runnable() {@Overridepublic void run() {}
}

3.3.3. 代码示例

    为了给大家演示匿名内部类的用法,接下来设计一个模拟按钮点击事件的案例。当我们进行安卓等设备开发时,面板上有个按钮,点击该按钮,如何监听点击事件?在 Android 系统中提供了各种对应的按钮点击监听事件。这里就通过实现接口的形式来定义匿名内部类,模拟一个单击事件。

 首先我们需要定义一个接口,表示单击监听,内部有个点击事件:

/*** 点击监听事件*/
public interface OnClickListener {// 点击事件void onClick();
}

然后定义一个 Button 按钮类,给 Button 按钮安排一个点击监听方法:

/*** 局部内部类 ---- 定义在方法中的内部类*/
public class Button {// 处理案例点击的监听事件public void setOnClickListener(OnClickListener listener) {listener.onClick();}
}

3.3.4. 代码测试

/*** 匿名内部类测试*/
public class AnonymousInnerClassTest {public static void main(String[] args) {// 外部变量int num = 20;// 测试匿名内部类Button btn = Button();// 模拟处理按钮的点击事件btn.setOnClickListener(new OnClickListener() { // 这里就是一个匿名内部类// 在匿名内部类中,可以允许使用非静态代码块进行成员初始化操作。int i;{ // 非静态代码块,在构造方法之后执行i = 100; // 成员初始化}@Overridepublic void onClick() {System.out.println("按钮被点击啦!i = " + i + ",num = " + num);}});}
}

根据上面的案例可知:

  • 在匿名内部类中,可以允许使用非静态代码块进行成员初始化操作;
  • 匿名内部类的非静态代码块,会在构造方法之后执行;
  • 匿名内部类也可以直接使用外部类的成员。

3.4. 静态内部类

    静态内部类和成员内部类的定义类似,但要使用 static 修饰,所以称为静态内部类(Static Nested Class)。

    静态内部类和成员内部类有很大的不同,它不再依附于 Outer 的实例,而是一个完全独立的类,因此无法引用 Outer.this 的方式调用。但它可以访问 Outer 类的 private 静态字段和静态方法,如果我们把静态内部类移到 Outer 类之外,就失去了访问 private 的权限。

3.4.1. 特点

  • 静态内部类中可以定义非静态的属性和方法,也可以定义静态的属性和方法;
  • 静态内部类中只能访问静态外部类的静态属性和方法。

3.4.2. 语法

创建静态内部类对象的基本语法格式如下:

// 内部类 对象名 = new 外部类.内部类();
Inner inner = new Outer.Inner();

3.4.3. 代码示例

    这里先简单定义一个静态内部类,在这个静态内部类中,定义了一个方法,来访问外部类中的普通属性和静态属性。我们要记住以下几点:

  • 静态内部类访问外部类的成员变量时,需要先创建外部类对象;
  • 非静态内部类可以直接访问使用外部类的成员变量,如同使用本类中的变量;
  • 所有的内部类访问外部类的静态变量时,可以直接通过 外部类.静态变量 的形式访问。

/*** 静态内部类*/
public class OuterClass {// 普通属性,属于外部类int outerAge = 28;static int outerNum = 10;// 定义一个静态的内部类,如果不带 static,就是一个普通的内部类。// 内部类的使用,和普通类一样,里面可以正常定义属性、方法、构造方法等。// static 前面可以带 public 等任意访问修饰符,也可以不带。static class InnerClass {// 私有属性无法在类的外部直接访问// private int innerNum = 20;int innerNum = 20;public void printNum() {// 定义外部类对象OuterClass outer = new OuterClass();// 这里的 this 是指 InnerClass 内部类对象!System.out.println("innerNum = " + this.innerNum + ",outerAge = " + outer.outerAge + ",outerNum = " + OuterClass.outerNum);}}
}

对于静态内部类而言,static 前面可以带 public 等任意访问修饰符,也可以不带。

3.4.4. 代码测试

我们再定义一个测试类,看看内部类对象是怎么调用的:

/*** 测试访问静态内部类*/
public class InnerClassTest {public static void main(String[] args) {// 创建内部类对象,格式为:外部类.内部类 对象名 = new 外部类.内部类的构造方法OuterClass.InnerClass inner = new OuterClass.InnerClass();// 调用内部类的方法inner.printNum();// 访问外部类属性System.out.println("outerNum = " + OuterClass.outerNum);// 访问内部类属性System.out.println("innerNum = " + inner.innerNum);}
}

3.4.5. 小结

对于静态内部类的访问要求,给大家总结如下:
1. 静态内部类中可以直接访问外部类的所有静态方法,包含私有的,但不能直接访问非静态成员;
2. 静态内部类可以添加任意访问修饰符(public、protected、default(默认)、private),因为它的地位就是一个成员;
3. 如果静态内部类 访问 外部类 的静态属性、静态方法等,访问方式是【直接访问】;
4. 如果外部类或外部的其他类来 访问 静态内部类,访问方式是【外部类.内部类 对象名 = new 外部类.内部类的构造方法】,创建出内部类对象后再访问。

四. 总结

我们来总结一下内部类的重点内容:

  • 内部类分为成员内部类、局部内部类、匿名内部类和静态内部类;
  • 成员内部类和匿名内部类在本质上是相同的,都必须依附于外部类的实例,会隐含地持有Outer.this 实例,并拥有外部类的 private 访问权限;
  • 静态内部类是独立类,但拥有外部类的 private 访问权限;
  • 如果外部类和内部类中的成员重名时,内部类访问时默认会遵循就近原则;如果想访问外部类的成员,则可以用【外部类名.成员】的形式来访问。

内部类的存在,具有如下优点:

  • 内部类使得多继承的解决方案变得更完整:每个内部类都能独立的实现接口,无论外部类是否已经实现了接口或继承了父类,对于内部类都没有影响;
  • 既可以方便地将存在一定逻辑关系的类组织在一起,又可以对外界隐藏;
  • 方便各类编写事件驱动程序;
  • 方便编写线程代码。 

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

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

相关文章

宋仕强论道之华强北精神和文化(二十一)

宋仕强论道之华强北精神和文化&#xff08;二十一&#xff09;&#xff1a; 华强北的精神会内化再提炼和升华成为华强北文化&#xff0c;在外部会流传下去和传播开来。在事实上的行动层面&#xff0c;就是华强北人的思维方式和行为习惯&#xff0c;即见到机会就奋不顾身敢闯敢赌…

C和C++的发展历史以及它们知识背景介绍

C和C发展历史 C语言 C语言是由贝尔实验室的丹尼斯里奇在20世纪70年代初期开发的。C语言最初被设计用于UNIX操作系统的开发&#xff0c;但后来被广泛用于其他各种领域和应用程序的编写。C语言是一种结构化编程语言&#xff0c;具有强大的底层系统编程能力&#xff0c;被广泛用…

pycharm多线程报错的问题(未解决)

暂未解决&#xff01; 看了一下可能是这里的问题&#xff1a; 根据建议&#xff0c;在walks之前加了 freeze_support() 但是没有效果。 关键是&#xff0c;在jupyter上运行是没有问题的&#xff01; 未解决。

js-过滤制表符

过滤所有不可见字符 var str"\n\t\n\t\t\t\r提问&#xff1a;亦庄上海沙龙房子保值吗" var reg /[\s]/g var re str.replace(reg,) console.log(re) console.log(JSON.stringify(re)) g全局匹配&#xff0c;默认只匹配一次 参考 JS——正则表达式&#xff08;超…

算法-05-二分查找

二分查找&#xff08;Binary Search&#xff09;算法&#xff0c;也叫折半查找算法&#xff0c;是一种针对有序数据集合的查找算法。 1-二分查找的思想 我们生活中猜数字的游戏&#xff0c;告诉你一个数据范围&#xff0c;比如0-100&#xff0c;然后你说出一个数字&#xff0c…

工业相机与镜头选型方法(含实例)

一、相机介绍及选型方法 1.工业相机介绍 工业相机与我们手机上面的相机或者我们单反相机不同,工业相机它能够使用各种恶劣的工作环境,比如说高温,高压,高尘等。工业相机主要有面阵相机和线阵相机,线阵相机主要用于检测精度要求很高,运动速度很快的场景,而面阵相机应用…

Leetcode刷题详解——字符串中的第一个唯一字符

1. 题目链接&#xff1a;387. 字符串中的第一个唯一字符 2. 题目描述&#xff1a; 给定一个字符串 s &#xff0c;找到 它的第一个不重复的字符&#xff0c;并返回它的索引 。如果不存在&#xff0c;则返回 -1 。 示例 1&#xff1a; 输入: s "leetcode" 输出: 0示…

spring 属性注入 @Autowired和@Resource注解使用

众所周知Resource 和 Autowired两大注解是开发中最常用的两大注解。两者有一定的区别&#xff1a; Autowired Autowired是spring框架提供的注解类&#xff0c;默认按照类型进行装配。当在容器中找不到对应类型的bean时会抛出NoSuchBeanDefinitionException异常&#xff0c;当…

C语言中的结构体成员赋值与访问详解

C语言中的成员赋值与访问 在C语言中&#xff0c;我们可以使用不同的方式对结构体变量的成员进行赋值和访问。本文将详细介绍这些方式&#xff0c;并通过具体的示例代码加以说明。 目录 使用strcpy_s函数赋值字符串直接赋值数字和浮点数结构体变量之间的赋值使用复合文字进行…

周周清(2)----踩坑日记

周一&#xff1a; 1.之前换了一个jdk&#xff0c;然后又改了很多东西&#xff0c;很乱&#xff0c;以至于很多项目都不能直接运行了&#xff0c;所以今天就将ideal删除并且更新版本到2022.3.3&#xff0c;并且重新将ideal里面的配置环境变量&#xff0c;以及jdk下载安装配置&a…

数据库系列之简要对比下GaussDB和OpenGauss数据库

GaussDB作为一款企业级的数据库产品&#xff0c;和开源数据库OpenGauss之间又是什么样的关系&#xff0c;刚开始接触的时候是一头雾水&#xff0c;因此本文简要对比下二者的区别&#xff0c;以加深了解。 1、GaussDB和OpenGauss数据库简要对比 GaussDB是华为基于PostgreSQL数据…

WPF仿网易云搭建笔记(4):信息流控制之消息订阅

文章目录 专栏和Gitee仓库前言消息订阅最简单的案例简单用例父组件订阅子组件回调 结果 消息订阅机制消息token是A还是B?传递消息的载体。双重token重复订阅问题 结论 专栏和Gitee仓库 WPF仿网易云 Gitee仓库 WPF仿网易云 CSDN博客专栏 前言 上一篇文章中&#xff0c;我们简单…

PHP基础(1)

PHP是一种服务器端脚本语言&#xff0c;是一种用于开发动态Web应用程序的最流行和广泛使用的语言之一。它的全称为“Hypertext Preprocessor”&#xff0c;是一种开源的、可嵌入HTML的脚本语言&#xff0c;可以嵌入到HTML中&#xff0c;也可以直接作为命令行脚本运行。PHP脚本在…

Java小案例-如果您的 Java 应用程序在不做任何事情时正在消耗 CPU,您如何确定它在做什么?

前言 我正在调用供应商的 Java API&#xff0c;在某些服务器上&#xff0c;JVM 在登录 API 后似乎进入了低优先级轮询循环&#xff08;CPU 使用率为 100%&#xff09;。其他服务器上的同一应用程序不会出现此行为。这发生在 WebSphere 和 Tomcat 上。环境设置起来很棘手&#…

DevOps搭建(四)-GitLab安装细步骤

在这里我们用docker安装 1、创建gitlab安装目录 mkdir -p /usr/local/docker/gitlab_docker 进入该目录 cd /usr/local/docker/gitlab_docker 2、下载gitlab镜像 docker pull gitlab/gitlab-ce:latest 3、创建docker-compose.yml vi docker-compose.yml 输入以下内容保…

理解 HTTP POST 请求:表单与 JSON 数据格式深入解析20231208

引言 在日常的 Web 开发中&#xff0c;理解 HTTP POST 请求的不同数据格式是至关重要的。这不仅有助于构建健壮的后端服务&#xff0c;还能确保与其他服务的有效沟通。本文将深入探讨 multipart/form-data 和 application/json&#xff0c;这两种常见的 POST 请求格式。 POST…

2023 年安徽省职业院校技能大赛高职组“软件测试”赛项样题

2023 年安徽省职业院校技能大赛 高职组“软件测试”赛项样题 目录 任务一&#xff1a;功能测试&#xff08;45 分&#xff09; 1、测试计划&#xff08;5 分&#xff09; 2、测试用例&#xff08;15 分&#xff09; 3、Bug 清单&#xff08;20 分&#xff09; 4、测试报告&…

Python 学习笔记之 networkx 使用

介绍 networkx networkx 支持创建简单无向图、有向图和多重图&#xff1b;内置许多标准的图论算法&#xff0c;节点可为任意数据&#xff1b;支持任意的边值维度&#xff0c;功能丰富&#xff0c;简单易用 networkx 中的 Graph Graph 的定义 Graph 是用点和线来刻画离散事物…

张驰咨询:数据驱动的质量改进,六西格玛绿带在汽车业实践

尊敬的汽车行业同仁们&#xff0c;您是否曾面临生产效率低下、成本不断攀升或顾客满意度下降的困扰&#xff1f;本期专栏&#xff0c;我们将深入探讨如何通过六西格玛绿带培训&#xff0c;在汽车行业中实现过程优化和质量提升。 汽车行业的竞争日趋激烈&#xff0c;致力于提供…

3.cloud-Consul服务注册与发现

1.官网 https://learn.hashicorp.com/consul/getting-started/install.html 2.订单服务 2.1 POM <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependenc…