Java常用类与基础API--String的实例化与连接操作

文章目录

  • 一、String实例化的两种方式
    • (1)两种方式
    • (2)举例
      • 1、案例1
      • 2、案例2
    • (3)内存分配
    • (4)面试题
      • 1、题1
      • 2、题2
  • 二、String的连接操作+
    • (1)案例
      • 1、案例剖析
      • 2、intern方法
    • (2)总结
  • 三、练习
    • (1)练习类型1:拼接
      • 1、题1
      • 2、题2
    • (2)练习类型2:new
      • 1、说明
      • 2、练习
    • (3)练习类型3:intern()
      • 1、说明
      • 2、题1
      • 3、题2
      • 4、题3
      • 5、题4

一、String实例化的两种方式

(1)两种方式

🔥两种方式

1种方式(字面量的方式):String s1 = "hello";

2种方式(String作为类):String s2 = new String("hello");

(2)举例

1、案例1

🌱代码

@Test
public void test1() {
    String s1 = "hello";
    String s2 = "hello";

    String s3 = new String("hello");
    String s4 = new String("hello");

    System.out.println(s1 == s2); //true
    System.out.println(s1 == s3); //false
    System.out.println(s1 == s4); //false
    System.out.println(s3 == s4); //false
}

🍺输出

image.png

false表示两个地址值不一样

2、案例2

🌱代码

@Test
public void test1() {
    String s1 = "hello";
    String s2 = "hello";

    String s3 = new String("hello");
    String s4 = new String("hello");

    System.out.println(s1.equals(s2));  //true
    System.out.println(s2.equals(s3));  //true
}

🍺输出

image.png

equals比较的是内容,所以都是true。

(3)内存分配

🎲内存是如何分配的呢?

String s="hello"; :在字符串常量池中有一个hello,将地址给了s。

字符串有一个属性叫value,value里面存储核心数据hello,hello是一个数组,所以value这里是一个引用。

String s=new String("hello"); 内存中是如何分配空间的?在内存中创建了几个对象?

🚗内存图

String s=new String("hello");

在内存空间中创建了两个对象

一个是在堆空间里面new的对象;一个是在常量池里面的String类型的hello,这个hello也有一个地址值。(因为字符串比较特别,在new的同时还要往字符串常量池里面放一个字面量)

image.png

两个对象如下:
image.png

这两个对象里面value的属性都指向同一个char型的数组,所以它们里面保留的地址(0X5566)是一样的,但外面来看它们的地址是不一样的(0X3344和0X1122)。

比如:

image.png

s1与s3的地址值就不一样,但是它们value属性的地址一致。

之前说过String内部声明的属性

  • jdk8中:private final char value[]; //存储字符串数据的容器
    • final : 指明此value数组一旦初始化,其地址就不可变。
  • jdk9开始:为了节省内存空间,做了优化private final byte[] value; //存储字符串数据的容器。

可以看到,声明value的时候,前面加了一个private,也就是value不对外暴露

所以,我们可以不用过多关注s1与s3它们内部的value指向的地址一致,只需要关注外面的地址不一致就好。

(4)面试题

1、题1

🌋String s2 = new String("hello");在内存中创建了几个对象?

两个

一个是堆空间中new的对象。另一个是在字符串常量池中生成的字面量

☕注意

有的小伙伴会有这个疑问,执行第一句代码的时候,已经在字符串常量池中造了一个了。

那么在执行第二句的时候就造一个堆空间里面的不就行了。

image.png

其实一般在问的时候,不考虑在字符串常量池中已经有的情况了。

直接问的时候,就说创建了两个对象即可。

2、题2

🌋下面代码输出结果是?

🌱代码

public class StringDemo1 {
    @Test
    public void test2(){
        Person p1=new Person();
        Person p2=new Person();
        p1.name="Tom";
        p2.name="Tom";

        p1.name="Jerry";
        System.out.println(p2.name);	//Tom

    }
}

class Person{
    String name;
}

🍺输出

image.png

☕分析

若是按照以往的思路,我们会觉得p1与p2的name是各自一份,下面修改了p1的name,不会影响p2的name,所以打印输出p2的name还是Tom

现在来看的话,p1与p2在内存中指向的是同一个位置。

<1> 对于p1

Person p1=new Person();

p1.name="Tom";

首先在堆里面new了一个Person,属性是name。然后用的是“字面量”的方式给它做的赋值,在字符串常量池里面有一个字符串Tom(数组中存放),它的地址赋值给了value(String的一个属性),然后String的地址(比如0x1122)赋值给了name。

最后Person的地址(比如0x3344)给了p1。

如下:

image.png

<2> 对于p2

Person p2=new Person();

p2.name="Tom";

同样的,在堆空间中新创建了一个对象,也会有一个地址值(比如0x5566),将它赋给了p2。

堆空间的对象有一个属性name,指向字符串常量池中的String(也是0x1122),value指向Tom。

image.png

可与看到,p1与p2它们在内存中使用了同一个Tom

以前我们画的是简略图

image.png


<3> 接下来,用p1调用name,并将它改为Jerry。

p1.name="Jerry";

此时详细的过程应该是:字符串常量池里面有一个“Jerry”,它的地址给了String的value,整一个新的地址。

然后p1的name指向的String的地址变成了0x7788。

如下:

image.png

<4> 现在用p2调用name,还是"Tom",不受影响。

System.out.println(p2.name);

这样设计的目的是为了节省内存空间。

当不同的属性(比如p1.name和p2.name)值是相同(比如"Tom")的时候,就让他们在字符串常量池里面共用同一个。

🎲为什么String要有不可变性?

我们看到的像是各自持有一份,但实际上用的是同一个。

假设现在有1000个用的都是Tom,是同一个Tom,若是其中一个想要改,不能在原有的地方改(要不然其他的都要一起变),要改的话自己新造一个,其他的不改就还用之前的那个。

这就极大节省了内存空间。

对于我们平常使用者来说,感受不到底层它们使用的是同一份。

只知道它们都有一个一样的值,其中一个修改不会影响其他的改变

共用一个节省了空间,在这个基础之上,谁想要改谁就自己重新造一个,不影响现有的对象使用当前的结果。

二、String的连接操作+

(1)案例

1、案例剖析

🌱代码

//测试String的连接符:+
@Test
public void test3(){
    String s1="hello";
    String s2="world";

    String s3="helloworld";
    String s4="hello"+"world";
    String s5=s1+"world";
    String s6="hello"+s2;
    String s7=s1+s2;

    System.out.println(s3==s4); //true
    System.out.println(s3==s5); //false
    System.out.println(s3==s6); //false
    System.out.println(s3==s7); //false

    System.out.println(s4==s5); //false
    System.out.println(s4==s6); //false
    System.out.println(s4==s7); //false

    System.out.println(s5==s6); //false
    System.out.println(s5==s7); //false

    System.out.println(s6==s7);	//false
}

🍺输出

image.png

🍰分析

false表示两者的地址是不一样的。

看一下反编译文件:

image.png

s3与s4已经写成一样的了。

在字节码文件当中,它就已经做了合并了。看到的是两个不同的字面量,其实编译之后就是一个拼接起来的。

所以s3==s4输出的是true

"hello"和"world"相当于是两个常量常量做拼接(“hello”+“world”)和直接写这个常量(“helloworld”)没有区别


`

s5、s6、s7中都有变量参与,变量参与的话该如何实现呢?

之前其实已经说过了,如下:

image.png

s2+="world"就相当于s2=s2+"world"

String s5=s1+"world"这种结构,其实是底层给new了一个对象。

看一下下面的解释(字节码文件):

image.png

总之,就是调用了StringBuildertoString,看一下:

public String toString(){
    //Create a copy,don't share the array
    return new String(value,0,count);
}

可以看到,这里面返回的是一个new了之后的对象。

所以,这里其实是新new的对象:(通过查看字节码文件发现,调用了StringBuildertoString()方法–>new String()

String s5=s1+"world";	//新new的对象
String s6="hello"+s2;	//新new的对象
String s7=s1+s2;	//新new的对象

因此,s5、s6、s7都是新new的对象,它们之间作比较,肯定都是不一样的。

s3是常量池里面的,跟堆空间里面new的对象显然也不是一致的,所以结果是false。


2、intern方法

🗳️补充

intern():调用这个方法后会得到一个新的字符串,返回的是字符串常量池中字面量的地址。

//测试String的连接符:+
@Test
public void test3(){
    String s1="hello";
    String s2="world";

    String s3="helloworld";
    String s4="hello"+"world";
    String s5=s1+"world";   //通过查看字节码文件发现,调用了StringBuilder的toString()方法-->new String()

    //...
    String s8=s5.intern();	//intern:返回的是字符串常量池中字面量的地址
    System.out.println(s3==s8);	//true
}

输出结果:

image.png

intern返回的是字符串常量池中字面量的地址,此时字符串常量池中已经有"helloworld"了,所以就将已有的地址返回给了s8。

因此,s3、s4、s8的地址是一样的

看一下内存图:

image.png

(2)总结

【String的连接操作:+

情况1

常量 + 常量:结果仍然存储在字符串常量池中,返回此字面量的地址

注:此时的常量可能是字面量,也可能是final修饰的常量。

比如:

🌱代码

String s1="hello";  //字面量,存储在常量池中
String s2="world";  //字面量

String s3="helloworld"; //字面量
String s4="hello"+"world";  //常量+常量,结果还在字符串常量池中

System.out.println(s3==s4); //true

再比如final修饰的常量:

🌱代码

public void test4(){
    final String s1="hello";  //字面量,存储在常量池中
    String s2="world";  //字面量

    String s3="helloworld"; //字面量
    String s4="hello"+"world";  //常量+常量,结果还在字符串常量池中
    String s5=s1+"world";   //通过查看字节码文件发现,调用了StringBuilder的toString()方法-->new String()
    String s6="hello"+s2;
    String s7=s1+s2;

    System.out.println(s3==s5); //true
    System.out.println(s3==s6); //false
}

s1前面加了一个final,就让它变成了常量

此时s5就跟s4类似了。

🍺输出

image.png

这种考的场景比较少。

情况2

常量 + 变量变量 + 变量 :都会通过new的方式创建一个新的字符串,返回堆空间中此字符串对象的地址。

🌱代码

String s1="hello";  //字面量,存储在常量池中
String s2="world";  //字面量

String s5=s1+"world";   //通过查看字节码文件发现,调用了StringBuilder的toString()方法-->new String()
String s6="hello"+s2;

System.out.println(s5==s6); //false

情况3

调用字符串的intern():返回的是字符串常量池中字面量的地址

🌱代码

String s1="hello";
String s3="helloworld"; //字面量
String s5=s1+"world";

String s8=s5.intern();  //intern():返回的是字符串常量池中字面量的地址

System.out.println(s3==s5); //false
System.out.println(s3==s8); //true

如果字符串常量池当中字面量不存在,就会新创建一个然后返回。

如果存在,就会返回已有的。(字符串常量池中不允许存放两个相同的字符串常量)

④(了解)情况4

concat(xxx):不管是常量调用此方法,还是变量调用,同样不管参数是常量还是变量,总之,调用完concat()方法都返回一个新new的对象

🌱代码

@Test
public void test5(){
    String s1="hello";
    String s2="world";

    String s3=s1.concat(s2);  //s1连接s2
    String s4="hello".concat("world");    //常量连接常量
    String s5=s1.concat("world");
    String s6="hello".concat(s2);

    System.out.println(s3==s4);
    System.out.println(s3==s5);
    System.out.println(s3==s6);
    System.out.println(s4==s5);
    System.out.println(s4==s6);
    System.out.println(s5==s6);

}

🍺输出

image.png

三、练习

(1)练习类型1:拼接

1、题1

🌱代码

String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2);	//true
// 内存中只有一个"hello"对象被创建,同时被s1和s2共享。

🍺输出

image.png

🍰分析

对应内存结构为:(以下内存结构以JDK6为例绘制):

image.png

进一步:
image.png

2、题2

🌱代码

@Test
public void test6(){
    Person p1 = new Person();
    p1.name = "Tom";

    Person p2 = new Person();
    p2.name = "Tom";

    System.out.println(p1.name.equals( p2.name)); //true
    System.out.println(p1.name == p2.name); //true
    System.out.println(p1.name == "Tom"); //true
}

🍰分析

在这里插入图片描述

🍺输出

image.png

(2)练习类型2:new

1、说明

String str1 = “abc”;String str2 = new String(“abc”);的区别?

image.png

str2 首先指向堆中的一个字符串对象,然后堆中字符串的value数组指向常量池中常量对象的value数组。

  • 字符串常量存储在字符串常量池,目的是共享。
  • 字符串非常量对象存储在堆中。

2、练习

🌱代码

@Test
public void test7(){
    String s1 = "javaEE";
    String s2 = "javaEE";
    String s3 = new String("javaEE");
    String s4 = new String("javaEE");

    System.out.println(s1 == s2);//true
    System.out.println(s1 == s3);//false
    System.out.println(s1 == s4);//false
    System.out.println(s3 == s4);//false
}

🍰分析

image.png

🍺输出

image.png

🎲问:String str2 = new String("hello"); 在内存中创建了几个对象?

两个

(3)练习类型3:intern()

1、说明

String s1 = "a";

说明:在字符串常量池中创建了一个字面量为"a"的字符串。

s1 = s1 + "b";

说明:实际上原来的“a”字符串对象已经丢弃了,现在在堆空间中产生了一个字符串s1+“b”(也就是"ab")。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能。

String s2 = "ab";

说明:直接在字符串常量池中创建一个字面量为"ab"的字符串。

String s3 = "a" + "b";

说明:s3指向字符串常量池中已经创建的"ab"的字符串。

String s4 = s1.intern();

说明:堆空间的s1对象在调用intern()之后,会将常量池中已经存在的"ab"字符串赋值给s4。

2、题1

🌱代码

@Test
public void test8(){
    String s1 = "hello";
    String s2 = "world";
    String s3 = "hello" + "world";
    String s4 = s1 + "world";
    String s5 = s1 + s2;
    String s6 = (s1 + s2).intern();

    System.out.println(s3 == s4);   //false
    System.out.println(s3 == s5);   //false
    System.out.println(s4 == s5);   //false
    System.out.println(s3 == s6);   //true
}

🍺输出

image.png

结论:
(1)常量+常量:结果是常量池。且常量池中不会存在相同内容的常量。
(2)常量与变量 或 变量与变量:结果在堆中
(3)拼接后调用intern方法:返回值在常量池中

3、题2

🌱代码

@Test
public void test01(){
	String s1 = "hello";
	String s2 = "world";
	String s3 = "helloworld";
		
	String s4 = s1 + "world";//s4字符串内容也helloworld,s1是变量,"world"常量,变量 + 常量的结果在堆中
	String s5 = s1 + s2;//s5字符串内容也helloworld,s1和s2都是变量,变量 + 变量的结果在堆中
	String s6 = "hello" + "world";//常量+ 常量 结果在常量池中,因为编译期间就可以确定结果
		
	System.out.println(s3 == s4);//false
	System.out.println(s3 == s5);//false
	System.out.println(s3 == s6);//true
}

@Test
public void test02(){
	final String s1 = "hello";
	final String s2 = "world";
	String s3 = "helloworld";
	
	String s4 = s1 + "world";//s4字符串内容也helloworld,s1是常量,"world"常量,常量+常量结果在常量池中
	String s5 = s1 + s2;//s5字符串内容也helloworld,s1和s2都是常量,常量+ 常量 结果在常量池中
	String s6 = "hello" + "world";//常量+ 常量 结果在常量池中,因为编译期间就可以确定结果
		
	System.out.println(s3 == s4);//true
	System.out.println(s3 == s5);//true
	System.out.println(s3 == s6);//true
}

@Test
public void test01(){
	String s1 = "hello";
	String s2 = "world";
	String s3 = "helloworld";
		
	String s4 = (s1 + "world").intern();//把拼接的结果放到常量池中
	String s5 = (s1 + s2).intern();
		
	System.out.println(s3 == s4);//true
	System.out.println(s3 == s5);//true
}

4、题3

🌱代码

public class TestString {
	public static void main(String[] args) {
		String str = "hello";
		String str2 = "world";
		String str3 ="helloworld";
		
		String str4 = "hello".concat("world");
		String str5 = "hello"+"world";
		
		System.out.println(str3 == str4);//false
		System.out.println(str3 == str5);//true
	}
}

concat方法拼接,哪怕是两个常量对象拼接,结果也是在堆。

5、题4

🌱代码

public class StringTest {

    String str = new String("good");
    char[] ch = { 't', 'e', 's', 't' };

    public void change(String str, char ch[]) {
        str = "test ok";
        ch[0] = 'b';
    }
    public static void main(String[] args) {
        StringTest ex = new StringTest();
        ex.change(ex.str, ex.ch);
        System.out.print(ex.str + " and ");//
        System.out.println(ex.ch);
    }
}

🍺输出

image.png

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++: const 的 权限放大缩小!

目录 概念 引用与const 关于上述的第一段代码&#xff1a; 关于上诉的第二段代码&#xff1a; const 使用指针进行权限的放大和缩小&#xff1a; 注意事项&#xff1a; const 与 成员函数 const 修饰 成员函数的规则&#xff1a; 概念 关于权限的放大和缩小问题&am…

【C++】【类和对象】拷贝构造函数

1.拷贝构造函数的特性&#xff1a; 1.拷贝构造函数用来构造一个与已存在对象一摸一样的对象 它只有单个形参&#xff0c;该形参是对本类类型对象的引用(一般常用const修饰)&#xff0c;在用已存在的类类型对象创建新对象时由编译器自动调用。 2.拷贝构造函数是构造函数的一种重…

gcore服务器设置root账号密码登录

这个厂商很奇怪&#xff0c;默认只能用centos用户与公钥登录&#xff0c;但是这样有时候很麻烦。 他默认开启了SELinux&#xff0c;和强制ssh密钥登录。 下面所有操作在root模式下进行 SELinux设置为兼容模式 setenforce 0vi /etc/selinux/config然后将文件中的SELINUXenfo…

分享88个表单按钮JS特效,总有一款适合您

分享88个表单按钮JS特效&#xff0c;总有一款适合您 88个表单按钮JS特效下载链接&#xff1a;https://pan.baidu.com/s/1v-qcl8bv2kxZ8a98Xo9UAg?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;…

滑动小短剧影视微信小程序源码/带支付收益等模式

仿抖音滑动小短剧影视微信小程序源码&#xff0c;带支付收益等模式、支持无限滑动&#xff1b;高性能滑动、预加载、视频预览&#xff0c;支持剧情介绍&#xff0c;集合壁纸另外仿抖音滑动效果&#xff1b;支持会员模式&#xff0c;支持用户单独购买等等多功能。 丰富的后台设…

备战蓝桥杯---数学基础3

本专题主要围绕同余来讲&#xff1a; 下面介绍一下基本概念与定理&#xff1a; 下面给出解这方程的一个例子&#xff1a; 下面是用代码实现扩展欧几里得算法&#xff1a; #include<bits/stdc.h> using namespace std; int gcd(int a,int b,int &x,int &y){if(b…

极狐GitLab 使用阿里云作为 OmniAuth 身份验证 provider

使用阿里云作为 OmniAuth 身份验证 provider 您可以启用阿里云 OAuth 2.0 OmniAuth provider并使用您的阿里云账户登录极狐GitLab。 创建阿里云应用 登录阿里云平台&#xff0c;在上面创建一个应用。阿里云会生成一个 client ID and secret key 供您使用。 登录到阿里云平台…

STM32Cubmax AD采集

一、基本概念 二、项目 AD函数结构体 typedef struct { uint32_t Mode; // ADC 工作模式选择 FunctionalState ScanConvMode; /* ADC 扫描&#xff08;多通道&#xff09; 或者单次&#xff08;单通道&#xff09;模式选择 */ FunctionalState ContinuousConvMode; // ADC 单…

【JavaEE】_HTML常用标签

目录 1.HTML结构 2. HTML常用标签 2.1 注释标签 2.2 标题标签&#xff1a;h1~h6 2.3 段落标签&#xff1a;p 2.4 换行标签&#xff1a;br 2.5 格式化标签 2.6 图片标签&#xff1a;img 2.7 超链接标签&#xff1a;a 2.8 表格标签 2.9 列表标签 2.10 表单标签 2.10…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 2月11日,星期日

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年2月11日 星期日 农历正月初二 1、 2024年总台春晚传播数据创下新纪录&#xff1a;全媒体累计触达267亿次&#xff0c;较去年增长29%。 2、 交通运输部&#xff1a;除夕全社会跨区域人员流动量超1.9亿人次。 3、 微信&am…

Backtrader 文档学习- Sizers

Backtrader 文档学习- Sizers 1.概述 智能仓位 Strategy提供了交易方法&#xff0c;即&#xff1a;buy&#xff0c;sell和close。看一下buy的定义&#xff1a; def buy(self, dataNone,sizeNone, priceNone, plimitNone,exectypeNone, validNone, tradeid0, **kwargs):注意&…

电子电器架构 —— 区域控制器是未来架构的正解吗?

电子电器架构 —— 区域控制器是未来架构的正解吗? 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶…

猫头虎分享已解决Bug || Go Error: panic: runtime error: index out of range

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

【PTA|期末复习|编程题】数组相关编程题(一)

目录 7-1 乘法口诀数列 (20分) 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 样例解释&#xff1a; 代码 7-2 矩阵列平移(20分) 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; …

JavaScript的聚焦:focus/blur

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ​ ✨ 正文 一、简介 focus 和 blur 事件是 HTML 元素的重要事件&#xff…

4、解构三个重要的Pipeline(SD-Inpainting, ControlNet, AnimateDiff) [代码级手把手解析diffusers库]

上一篇我们解析了所有Pipeline的基类DiffusionPipeline。后续各种各样的pipeline都继承了DiffusionPipeline的模型加载保存等功能,然后再配合各个组件实现各种的结构即可。 事实上,一个Pipeline通常包含了如下模块(from_pretrained函数根据model_index.json文件new了一个Pipe…

还在用findViewById,不来了解下其它方式?

众所周知&#xff0c;都2220年了&#xff0c;findViewById已经是一种非常繁琐的操作&#xff0c;如果要去获取的id数量多&#xff0c;则对开发更加不友好。如果一个页面id过多&#xff0c;经常会有如下场景&#xff1a; TextView title findViewById(R.id.*tv_title*); TextV…

数据结构(2) 线性表

线性表 线性表的定义线性表的基本操作lnitList(&L)DestroyList(&L)Listlnsert(&L,i,e)ListDelete(&L,i,&e)LocateElem(L,e)GetElem(L,i)Length(L)PrintList(L)Empty(L)Tips:引用值 小结 根据数据结构的三要素–逻辑结构、数据的运算、存储结构&#xff0c;…

【教3妹学编程-算法题】使数组异或和等于 K 的最少操作次数

3妹&#xff1a;2哥&#xff0c;新年好鸭~ 2哥 : 新年好&#xff0c;3妹这么早啊 3妹&#xff1a;是啊&#xff0c;新年第一天要起早&#xff0c;这样就可以起早一整年 2哥 :得&#xff0c;我还不了解你&#xff0c;每天晒到日上三竿 3妹&#xff1a;嘿嘿嘿嘿&#xff0c;一年是…

【JMX】JAVA监控的基石

目录 1.概述 2.MBean 2.1.Standard MBean 2.2.Dynamic MBean 2.3.Model Bean 2.4.Dynamic MBean和Model Bean的区别 2.5.MXBean 2.6.Open Bean 3.控制台 1.概述 什么是JMX&#xff0c;首先来看一段对话&#xff1a; Java Management Extensions&#xff08;JMX&#…