栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java基础

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java基础

目录

1.Java简介

1.1什么是Java1.2Java的应用领域1.3Java的版本1.4Java语言的特性 2.Java语言基础

2.1.Java主类结构

2.1.1输出Hello World!2.1.2包声明2.1.3声明成员变量和局部变量2.1.4编写主方法2.1.5导入API类库 2.2基本数据类型

2.2.1整数类型2.2.2浮点类型2.2.3字符类型

2.2.3.1char型2.2.3.2转义字符 2.2.4布尔类型 2.3变量与常量

2.3.1标识符和关键字

1.标识符2.关键字 2.3.2声明变量2.3.3声明常量2.3.4变量的有效范围

2.3.4.1成员变量2.3.4.2局部变量 2.4运算符

2.4.1赋值运算符2.4.2算术运算符2.4.3自增和自减运算符2.4.4比较运算符2.4.5逻辑运算符2.4.6位运算符

1按位与2按位或3按位取反4按位异或5移位操作6三目运算符7.运算符优先级 2.5数据类型转换

2.5.1隐式类型转换2.5.2显式类型转换 2.6代码注释与编程规范

2.6,1代码注释2.6,2编码规范 3.流程控制

3.1复合语句3.2条件语句

3.2.1if条件语句3.2.2switch条件语句 3.3循环语句

3.3.1 while循环语句3.3.2 do...while循环语句3.3.3 for循环语句 3.4循环控制

3.4.1break语句3.4.2continue语句 4.字符串

4.1String类

4.1.1声明字符串4.1.2创建字符串 4.2连接字符串

4.2.1连接多个字符串4.2.2连接其他数据类型 4.3获取字符串信息

4.3.1获取字符串长度4.3.2字符串查找4.3.3获取指定索引位置的字符 4.4字符串操作

4.4.1获取子字符串4.4.2去除空格4.4.3字符串替换4.4.4判断字符串的开始与结尾4.4.5判断字符串是否相等4.4.6按字典顺序比较两个字符串4.4.7字母大小写转换4.4.8字符串分割 4.5格式化字符串

4.5.1日期和时间字符串格式化4.5.2常规类型格式化 4.6使用正则表达式4.7字符串生成器 5.数组

5.1数组概述5.2一维数组的创建及使用

5.2.1先声明,再进行内存分配5.2.2初始化一维数组5.2.3使用一维数组 5.3二维数组的创建及使用

5.3.1二维数组的创建5.3.2二维数组初始化5.3.3使用二维数组 5.4数组的基本操作

5.4.1遍历数组5.4.2填充替换数组元素5.4.3对数组进行排序5.4.4复制数组5.4.5数组查询 5.5数组排序算法

5.5.1冒泡排序5.5.2直接选择排序5.5.3反转排序 6.类和对象

6.1面向对象概述

6.1.1对象6.1.2类6.1.3封装6.1.4继承6.1.5多态 6.2类

6.2.1成员变量6.2.2成员方法6.2.3权限修饰符6.2.4局部变量6.2.5局部变量的有效范围6.2.6 this关键字 6.3类的构造方法6.4静态变量、常量和方法6.5类的主方法6.6对象

6.6.1对象的创建6.6.2访问对象的属性和行为6.6.3对象的引用6.6.4对象的比较6.6.5对象的销毁 7.包装类

7.1Integer

7.1.1构造方法7.1.2常用方法7.1.3常量 7.2Boolean

7.2.1构造方法7.2.2.常用方法7.2.3.常量 7.3Byte

7.3.1构造方法7.3.2常用方法7.3.3常量 7.4Character

7.4.1构造方法7.4.2常用方法7.4.3常量 7.5Double

7.5.1构造方法7.5.2常用方法7.5.3常量 7.6Number
第一篇初识Java

1.Java简介 1.1什么是Java

1.Java是一门高级的面向对象的程序设计语言用
2.Java语言是跨平台的
3.Java程序可以在任何计算机,操作系统以及支持Java的硬件设备上运行.

1.2Java的应用领域

1.桌面应用系统开发
2.嵌入式系统开发
3.电子商务应用
4.企业级应用开发
5.交互式系统开发
6.多媒体系统开发
7.分布式系统开发
8.Web应用系统开发

1.3Java的版本

1.Java SE
是Java的标准版,主要用于桌面应用程序的开发,同时也是Java的基础,包含了Java语言基础,JDBC(Java数据库连接性)操作,I/O,网络通信,多线程等技术.
2.Java EE
是Java的企业版,主要用于开发企业级分布式的网络程序,核心是EJB(企业Java组件模型)
3.Java ME
主要应用于嵌入式系统开发,如电脑,手机等移动通信电子设备.

1.4Java语言的特性

1.简单
2.面向对象
3.分布性
4.可移植性
5.解释型
6.安全性
7.健壮性
8.多线程
9.高性能
10.动态

2.Java语言基础 2.1.Java主类结构 2.1.1输出Hello World!

Java语言是面向对象的编程语言,java程序的基本组成单位是类,类体中属性与方法.每个应用程序都必须包含一个main()方法,含有main()方法的类称为主类.
如下图所示,输出Hello World!

package my;

public class Hello {

	public static void main(String[] args) {
		
		System.out.println("Hello World!");

	}

}

2.1.2包声明

一个Java应用程序是由若干个类组成的,package为包的关键字,主要为了方便管理不同的类.

2.1.3声明成员变量和局部变量

通常将类的属性称为类的全局变量(成员变量),将方法中的属性称为局部变量.全局变量声明在类体中,局部变量声明在方法体中,例如:

package my;

public class Hello {
	//成员变量
	public int a;

	public static void main(String[] args) {
		//局部变量
		int b = 10;
	

	}

}

2.1.4编写主方法

1.main()方法是类体中的主方法.
2.该方法从"{“开始,至”}"结束.
3.Java中main方法必须声明为public static void.
4.String[] args 是一个字符串类型的数组,它是main方法的参数
5.main方法是程序开始执行的位置

2.1.5导入API类库

在Java语言中可以通过import关键字导入相关的类.在JDK的API中提供了130多个包,API文档是程序开发人员不可获取的工具.

2.2基本数据类型 2.2.1整数类型

整数类型用来存储整数数值,即没有小数部分的数值.可以是正数,也可以是负数.整型数据在Java程序中有三种表示形式,分为十进制,八进制和十六进制.
1.十进制:
如12,3,127
2.八进制:
0123,-0123
3.十六进制:
0x25,
整型数据类型根据它所占的内存大小不同,可以分为byte,short,int和long4种类型.具有不同的取值范围,如下表:

注意,对于long数值,若赋值给大于int的最大值或int的最小值,则需要在数字后加L或l,表示该数值为长整型.
如 long sum = 2147483650l

package my;

public class Hello {
	
	public static void main(String[] args) {
		byte a = 10;
		short b = 32333;
		int c = 2147000000;
		long d = 2147483650l;

	}

}

2.2.2浮点类型

浮点类型表示有小数部分的数字.Java语言中浮点类型分为单精度浮点类型(float)和双精度浮点类型(double),具有各自不同的取值范围.

注意:在默认情况下,小数都被看做double型,若使用float型小数,则需要在小数后面加F或f.使用后缀d或D来明确表示这是一个double类型数据.

        float f1 = 13.14f;
		double f2 = 245.566d;
		double f3 = 345.45645;
2.2.3字符类型 2.2.3.1char型

1.字符类型用于存储单个字符串,占用16位的内存空间.
2.定义字符变量时,要以单引号表示
3.关键字char

char x = 'a';
2.2.3.2转义字符

转义字符是一种特殊的字符变量,以反斜杠""开头,后跟一个或多个字符.

2.2.4布尔类型

1布尔类型又称逻辑类型
2.关键字boolean
3.只有true 和 false两个值

2.3变量与常量 2.3.1标识符和关键字 1.标识符

1.标识符可以简单地理解为一个名字,用来标识类名,变量名,方法名,数组名,文件名的有效字符序列.
2.java语言规定标识符可以由任意的字母,下划线,美元符号$和数字组成,并且第一个字符不能是数字.
3.标识符不能是java中的关键字

2.关键字

关键字是Java语言中已经被赋予特定意义的一些单词,不可以把这些作为标识符来使用.
Java关键字表:

2.3.2声明变量

变量的使用是程序设计中一个十分重要的环节.定义变量就是要告诉编译器这个变量的数据类型,这样编译器才知道需要配置多少空间给它./

//声明int型变量
int id;
//声明char型变量
char c;

变量名的命名规则:
1.变量名必须是一个有效的标识符
2.变量名不可以使用Java中的关键字
3.变量名不能重复
4.应选择有意义的单词作为变量名

2.3.3声明常量

1.在程序运行过程中一直不会改变的量称为常量(constant),通常也称为"final变量".常量在整个程序中只能被赋值一次.
2.在为所有的对象共享值时,常量是非常有用的.

final double Pi = 3.1415926D;
2.3.4变量的有效范围

由于变量被定义出来后只是暂存在内存中,等到程序执行某一个点,该变量会被释放掉,也就是说变量有它的生命周期.因此,变量的有效范围是指程序代码能够访问该变量的区域,若超出该区域,则在编译时会出现错误.

2.3.4.1成员变量

在类体中所定义的变量称为成员变量,成员变量在整个类中都有效.成员变量分为两类,即静态变量和实例变量.

package my;

public class First {
	int x = 45;
	static int y =520;
}

如上述中的x为实例变量,y为静态变量.如果加static修饰,这样的变量就称为静态变量.静态变量的有效范围可以跨类,甚至可以达到整个应用程序之内.能直接以类名.静态变量的方式在其他类中使用.

2.3.4.2局部变量

在类的方法体中定义的变量称为局部变量.局部变量只在当前代码块中有效.
1.在类的方法中声明的变量,包括方法的参数,都属于局部变量.
2.局部变量只在当前定义的方法内有效,不能用于类的其它方法体中.
3.局部变量的生命周期取决于方法,当方法被调用时,Java虚拟机为方法中的局部变量分配内存空间,当该方法的调用结束后,则会释放方法中局部变量占用的内存空间,局部变量也会被销毁.
4.局部变量可与成员变量的名字相同,此时成员变量将被隐藏,即这个成员变量在此方法中暂时失效.

package my;

public class First {
	//成员变量
	int x = 45;
	public void haha()
	{
		//局部变量
		int y = 520;
	}
}

2.4运算符 2.4.1赋值运算符

赋值运算符用符号"="表示,它是一个二元运算符(对两个操作数进行处理),其功能是将右方操作数所含的值赋给左方的操作数.

int a = 100;
2.4.2算术运算符

2.4.3自增和自减运算符

1.自增,自减运算符是单目运算符,可以放在操作元之前,也可以放在操作元之后.
2.操作元必须是一个整型或浮点型变量.自增,自减运算符的作用是使变量的值增1或者减1.
3.运算符放在操作元之前会将变量的值加1(减1),然后再使该变量与表达式计算.
4.运算符放在操作元之后会先使该变量与表达式计算.然后再将变量的值加1(减1).

package my;

public class Hello {
	
	public static void main(String[] args) {
		int a = 1;
		int b = ++a;//b的值为2
		a = 1;
		b = a++;    //b的值为1
	}

}

2.4.4比较运算符

比较运算符属于二元运算符,用于程序中的变量之间,比较运算符的运算结果是boolean型.当关系成立,运算结果为true,否则为false.

2.4.5逻辑运算符

返回类型为布尔值的表达式

2.4.6位运算符

1.位运算符除"按位与","按位或"外,其他只能用于处理整数的操作数
2.位运算是完全针对位方面的操作.
3.整型数据在内存中以二进制的形式表示,如int型变量7的二进制表示是
00000000 00000000 00000000 0000111左边最高位是符号位,最高位0表示正数,若为1表示负数

1按位与

符号为"&",为双目运算符.法则:如果两个整型数据a,b对应位都是1,则结果位才是1,否则为0.如果两个操作数的精度不同,则结果的精度与精度高的操作数相同.

2按位或

符号为"|",为双目运算符.法则:如果两个整型数据a,b对应位都是0,则结果位才是0,否则为1.如果两个操作数的精度不同,则结果的精度与精度高的操作数相同.

3按位取反

运算符"~",为单目运算符.按位取反就是将操作数二进制中的1修改为0,0修改为1.

4按位异或

运算符"^",为双目运算符.当两个操作数的二进制表示相同(同时为0或者同时为1)时,结果为0,否则为1.

5移位操作

1.左移<<
2,右移>>
3.无符号右移>>>
左移就是将运算符左边的操作数的二进制数据,按照运算符右边操作数指定的位数向左移动,右边移空的部分补0.
右移,如果最高位是0,右移空的位就填入0,如果最高位是1,右移空的位就填入1.

无符号右移:无论最高位是0还是1,左侧被移空的高位都填入0

6三目运算符

1.格式:
条件式?值1:值2
2.规则:
若条件式的值为true,则整个表达式取值1,否则取值2
3.等价于if…else语句

boolean b = 20 < 45 ? true:false;
7.运算符优先级

运算符的优先级决定了表达式中运算执行的先后顺序.

2.5数据类型转换

类型转换是将一个值从一种类型更改为另一种类型的过程.

2.5.1隐式类型转换

从低级类型向高级类型的转换,系统将自动执行,这种称为隐式转换.
转换规则:


例如上述int就自动转换为double

2.5.2显式类型转换

当把高精度的变量的值赋给低精度的变量时,必须使用显式类型转换运算(又称强制类型转换),语法:
(类型名)要转换的值

int a = (int)123.01;

此时a的值为123

2.6代码注释与编程规范 2.6,1代码注释

通过在程序代码中添加注释可提高程序的可读性
1.单行注释
从符号//开始直到换行为止的所有内容均作为注释而被编译器忽略
2.多行注释
符号//之间的所有内容均为注释内容
3.文档注释

2.6,2编码规范

1.每条语句要单独占一行,一条命令要以分号结束
2.在声明变量时,尽量使每个变量的声明单独占一行
3.在Java代码中,关键字之间如果有多个空格则视为一个
4.为了方便日后的维护,不要使用技术性很高,难懂,易混淆的语句.由于程序的开发与维护不能是同一个人,所以应尽量使用简单的技术完成程序需要的功能
5.对于关键的方法要多加以注释,这样有助于阅读者了解代码结构.

3.流程控制 3.1复合语句

1.Java语言的复合语句是以整个块区为单位的语句,所以又称块语句.
2.复合语句由开括号"{“开始,闭括号”}"结束.
3.复合语句为局部变量创建了一个作用域.

3.2条件语句

条件语句可根据不同的条件执行不同的语句,包括if条件语句和Switch条件语句.

3.2.1if条件语句

1.简单的if条件语句
if(布尔表达式)
{
语句序列
}

int a = 10;
		if(a == 10)
		{
			System.out.println(a);
		}

2.if…else语句
if(表达式){
若干语句
}
else
{
若干语句
}

int a = 10;
		int b = 520;
		if(a > b )
		{
			System.out.println(a);
		}
		else
		{
			System.out.println(b);
		}

3.if…else if多分支语句
if…else if多分支语句用于针对某一事件的多种情况进行处理.

int a = 10;
		int b = 520;
		if(a > b )
		{
			System.out.println(a);
		}
		else if(a == b)
		{
			System.out.println(b);
		}
		else
		{
			System.out.println(a+b);
		}
3.2.2switch条件语句

switch(表达式)
{
case 常量值1:
语句块
[break]
case 常量值2:
语句块
[break]

case 常量值n:
语句块
[break]
}
switch语句中的表达式的值必须是整型,字符型或字符串类型,switch语句首先计算表达式的值和某个case后面的常量值相同,则执行该case语句后的若干语句直到遇到break语句为止.此时如果该case语句中没有break语句,将继续执行后面case中的若干个语句,直到遇到break语句为止.若没有一个常量的值与表达式的值相同,则执行default后面的语句.default语句为可选的.

如上图所示switch语句输出3

3.3循环语句

循环语句就是在满足一定条件的情况下反复执行某一个操作.

3.3.1 while循环语句

while(条件表达式)
{
执行语句
}
当条件表达式的返回值为真时,则执行"{}“中的语句,当执行完”{}"中的语句后,重新判断条件表达式的返回值,直到表达式返回的结果为假时,退出循环.

3.3.2 do…while循环语句

与while语句类似,他们之间的区别就是while语句为先判断条件是否成立再执行循环体,二do…while语句则先执行一次循环后,再判断条件是否成立.

3.3.3 for循环语句

for循环是Java程序设计中最有用的循环语句之一.一个for循环可以用来重复执行某条语句,直到某个条件得到满足.
1.for语句
for(表达式1;表达式2;表达式3)
{
语句序列
}
表达式1:初始化表达式,负责完成变量的初始化
表达式2:循环条件表达式,值为boolean型的表达式,指定循环条件
表达式3:循环后操作表达式,负责修整变量,改变循环条件.

2.foreach循环语句
foreach语句是for语句的特殊简化版本,不能完全取代for语句,但任何foreach都可以改写for语句版本.
foreach并不是一个关键字,习惯上将这种特殊的for语句格式称为foreach语句.foreach在遍历数组等时很方便.
for(元素变量x:遍历对象obj)
{
引用了x的Java语句
}
foreach语句中的元素变量x,不必对其初始化.

int arr[] = {1,2,3,4};
		for(int e:arr)
		{
			System.out.println(e);
		}
3.4循环控制

循环控制包含两方面的内容,一方面是控制循环变量的变化方式,另一方面是控制循环的跳转.

3.4.1break语句

使用break语句可以跳出当前循环体.例如:

当e==2使跳出循环体
如果想让break跳出一层以上的循环,Java提供了标签功能.
标签名: 循环体
{
break标签名;
}
标签名:任意标识符
循环体:任意循环语句
break标签名:break跳出指定的循环体,此循环体的标签名必须与break的标签名一致.

package my;

public class Hello {
	
	public static void main(String[] args) {
		int sum = 0;
		LOOP:for(int i =0;i<5;i++)
		{
			for(int j = 0;j<5;j++)
			{
				sum += i*j;
				if(sum>10)
				{
					break LOOP;
				}
			}
		}
			System.out.println(sum);
		
	}

}

3.4.2continue语句

continue语句是对break语句的补充.continue语句不是立即跳出循环体,而是跳出本次循环结束前的语句,回到循环的条件测试部分,重新开始执行循环.

package my;

public class Hello {
	
	public static void main(String[] args) {
		int sum = 0;
		int a = 10;
		while(a>0)
		{
			a--;
			if(a%2 == 0)
			{
				System.out.println(a);
				a--;
				continue;
			}
		}
			System.out.println(sum);
		
	}

}

4.字符串 4.1String类

在Java语言中将字符串作为对象来处理,可以通过java.lang包中的String类来创建字符串对象.

4.1.1声明字符串

在Java中字符串必须包含在一对双引号内.如:“abc”
声明字符串变量

String str;

1.String:指定该变量为字符串类型
2.str:任意有效的标识符,表示字符串变量的名称

4.1.2创建字符串

创建对象要使用类的构造方法.常用构造方法如下:
1.String(char a[])
用一个字符数组a创建String对象

        char a[] = {'l','i','n'};
		String s = new String(a);

等价于

String s = new String("lin");

2.String(char a[],int offset,int length)
offset表示开始截取字符串的位置,length表示截取字符串的长度

char a[] = {'s','t','u','d','e','n','t'};
String s = new String(a,2,4);

等价于

String s = new String("uden");

3.String(char value())
该构造方法可分配一个新的String对象,使其表示字符数组参数中所有元素连接的结果.

char a[] = {'s','t','u','d','e','n','t'};
String s = new String(a);

等价于

String s = new String("student");
4.2连接字符串 4.2.1连接多个字符串

使用"+“运算符可实现连接多个字符串的功能.”+"运算符可以连接多个运算符并产生一个String对象.

4.2.2连接其他数据类型

字符串也可同其他基本数据类型进行连接.如果将字符串同这些数据类型进行连接,会将这些数据直接转换成字符串.

4.3获取字符串信息 4.3.1获取字符串长度

4.3.2字符串查找

String类提供了两种查找字符串的方法,即indexOf()和lastIndexOf().
1.indexOf(String s)
该方法用于返回参数字符串s在指定字符串中首次出现的索引位置.当调用字符串的indexOf()方法时,会从当前字符串的开始位置搜索s的位置.如果没有检索到字符串s,该方法的返回值是-1.
str.indexOf(substr)
str:任意字符串对象
substr:要搜索的字符串

2.lastIndexOf(String str)
该方法用于返回指定字符串最后一次出现的索引位置.当调用该方法时,会从当前字符串的开始位置检索参数字符串str,并将最后一次出现str的索引位置返回.如果没有检索到字符串str,该方法返回-1.

4.3.3获取指定索引位置的字符

使用charAt()方法可将指定索引处的字符返回

4.4字符串操作 4.4.1获取子字符串

1.substring(int beginindex)
该方法返回的是从指定索引位置开始截取直到该字符串结尾的字串

2.substring(int beginIndex,int endIndex)
该方法返回的是从字符串某一索引位置开始截取至某一索引位置结束的字串

4.4.2去除空格

trim()方法返回字符串的副本,忽略前导空格和尾部空格

4.4.3字符串替换

replace()方法可实现将指定的字符或字符串替换成新的字符或字符串
str.replace(char oldChar,char newChar)

4.4.4判断字符串的开始与结尾

1.startWith()方法
该方法用于判断当前字符串对象的前缀是否为参数指定的字符串

2.endsWith()
该方法用于判断当前字符串是否以给定的子字符串结束

4.4.5判断字符串是否相等

对字符串对象进行比较不能简单地使用比较运算符"==",因为比较运算符比较的是两个字符串的地址是否相同,两个对象的内存地址也是不同的,使用比较运算符仍然会返回false.

在debug模式下可以看到两个字符串的地址是不同的.
1.equals()方法
如果两个字符串具有相同的字符和长度,则使用equals方法进行比较时,返回true

2.equalsIgnoreCase()
使用equals()对字符串进行比较时是区分大小写的,而equalsIgnoreCase()是在忽略了大小写的情况下比较两个字符串是否相等,相等返回true

4.4.6按字典顺序比较两个字符串

1.compareTo()方法为按字典顺序比较两个字符串,该比较基于字符串中各个字符的Unicode值,按字典顺序将此String对象表示的字符序列与参数字符串所表示的字符序列进行比较
2.如果按字典顺序此String对象位于参数字符串之前,则比较结果为一个负整数.
3.如果按字典顺序此String对象位于参数字符串之后,则比较结果为一个正整数.
4.如果这两个字符串相等,则结果为0

4.4.7字母大小写转换

1.toLowerCase()
该方法将String对象转换为小写

2.toUpperCase()
该方法将String对象转换为大写

4.4.8字符串分割

使用split()方法可以使字符串按指定的分割字符或字符串对内容进行分割,并将分割后的结果存放在字符串数组中.
1.split(String sign)
该方法可根据给定的分割符对字符串进行拆分

1.split(String sign,int limit)
根据给定的分割符对字符串进行拆分,并限定拆分的次数

4.5格式化字符串

String类的静态format()方法用于创建格式化的字符串
1.format(String format,Object…args)
该方法使用指定的格式字符串和参数返回一个格式化字符串,格式化后的新字符串使用本地默认的语言环境
format:格式字符串
args:格式字符串中由格式说明符引用的参数,如果还有格式说明符以外的参数,则忽略这些额外的参数.此参数的数目是可变的,可以为0.
类似于c语言中的printf()函数

2.format(Local 1,String format,Object…args)
1:格式化过程中药应用的语言环境.如果1位null,则不进行本地化

4.5.1日期和时间字符串格式化

1.日期格式化
返回一个月中的天数

常用的日期格式化转换符

2.时间格式化
时间格式化转换符


3.格式化常见的日期 时间组合

4.5.2常规类型格式化


4.6使用正则表达式

正则表达式通常被用于判断语句中,用来检查某一字符串是否满足某一格式.正则表达式是含有一些具有特殊意义字符的字符串,这些特殊字符称为正则表达式的元字符.


在正则表达式中".“代表任何一个字符,因此在正则表达式中如果想使用普通意义的点字符”.",必须使用转义字符"".
在正则表达式中可以使用方括号括起若干个字符来表示一个元字符,该元字符可代表方括号中的任何一个字符.例如,reg="[abc]4",这样字符串a4,b4,c4都是和正则表达式匹配的字符串.
1 [^456]:代表4,5,6之外的任何字符
2 [a-r]:代表a~r中的任何一个字母
3. [a-zA-Z]:可表示任意一个英文字母
4. [a-e[g-z]]代表a-e或g-z中的任何一个字母(并运算)
5. [a-o&&[def]]:代表字母d,e,f(交运算)
6. [a-d&&[^bc]]:代表字母a,d(差运算)
在正则表达式中允许使用限定修饰符来限定元字符出现的次数.例如"A*"代表A可以在字符串中出现0次或多次


4.7字符串生成器

创建成功的字符串对象,其长度是固定的,内容不能被改变和编译.虽然使用"+“可以达到附加新字符或字符串的目的,但”+"会产生一个新的String实例,会在内存中创建新的字符串对象,如果重复地对字符串进行修改,将极大地增加系统开销.J2SE 5.0新增了可变的字符序列String-Buildder类,大大提高了频繁增加字符串的效率.

通过这一实例可以看出,两种操作执行的时间差距很大.如果在程序中频繁地附加字符串,建议使用StringBuilder.新创建的StringBuileder对象初始容量是16个字符,可以自行指定初始长度.如果附加的字符超过可容纳的长度,StringBuilder对象将自动增加长度以容纳被附加的字符.若要使用StringBuilder最后输出字符串结果,可使用toString方法.
1.append()
该方法用于向字符串生成器中追加内容,可实现接受任何类型的数据,
append(content)
2.insert(int offset,arg)
该方法用于向字符串生成器中的指定位置插入数据内容.
offset:字符串生成器的位置
arg:将插入至字符串生成器的位置,该参数可以是任何的数据类型或其他对象

3.delete(int start,int end)
移除此序列的子字符串中的字符.该子字符串从指定的start处开始,一直索引到end-1处的字符,如果不存在这种字符,则一直到序列尾部.如果start等于end,则不发生任何更改.

5.数组

科普:
数组是最为常见的一种数据结构,是相同类型的用一个标识符封装到一起的基本类型数据序列或对象序列.可以用一个统一的数组名和下标来唯一确定数组中的元素.实质上,数组是一个简单的线性序列,因此访问速度很快.

5.1数组概述

数组是具有相同数据类型的一组数据的集合.数组中的每个元素具有相同的数据类型.在Java中同样将数组看做一个对象,虽然基本数据类型不是对象,但由基本数据类型组成的数组却是对象.可根据数组的维数将数组分为一维数组,二维数组.

5.2一维数组的创建及使用 5.2.1先声明,再进行内存分配

声明

int arr[];
String[] arr2;

声明数组后,还不能立即访问它的任何元素,因为声明数组只是给出了数组名字和元素的数据类型,要想真正使用数组,还要为它分配内存空间.在分配空间时必须指明数组的长度.

arr = new int[5]

创建一个有5个元素的整型数组,并且将创建的数组对象赋给引用变量arr,即引用变量arr引用这个数组数组的下标是从0开始的.五个元素,那么数组中的下标就是0~4
2.声明数组的同时为数组分配内存

int a[] = new int[5];
5.2.2初始化一维数组

数组的初始化有两种形式

		int a[] = new int[] {1,2,3,4,5};
		int arr[] = {1,2,3,4,5};
5.2.3使用一维数组

5.3二维数组的创建及使用

如果一维数组中的各个元素仍然是一个数组,那么它就是一个二维数组.二维数组常用来表示表,表中的信息以行和列的形式组织,第一个下标代表元素所在的行,第二个下标代表元素所在的列.

5.3.1二维数组的创建

1.先声明,再用new运算符进行内存分配
声明

int a[][];

内存分配

a = new int[5][];

2.声明的同时为数组分配内存

int a[][] = new int[5][];
5.3.2二维数组初始化
int arr[][]= {{1,2,3},{2,3,4}};
5.3.3使用二维数组

创建一个矩阵

5.4数组的基本操作

java.util包的Arrays类包含了用来操作数组(如排序和搜索)的各种方法.

5.4.1遍历数组

遍历数组就是获取数组中的每个元素.通常遍历数组都是使用for循环来实现.遍历一维数组很简单,也很好理解.
遍历二维数组需使用双层for循环,通过数组的length属性可获得数组的长度.

在遍历数组时,使用foreach语句可能会更简单.

5.4.2填充替换数组元素

数组中的元素定义完成后,可通过Arrays类的静态方法fill()来对数组中的元素进行替换.该方法通过各种重载形式可完成对任意类型的数组元素的替换.
1.fill(int[] a,int value)
a:要进行元素替换的数组
value:要储存数组中所有元素的值

2.fill(int[] a,int fromIndex,int toIndex,int value)
该方法将指定的int值分配给int型数组指定范围中的每个元素.填充的范围从索引fromIndex(包括)一直到索引toIndex(不包括).如果fromIndex == toIndex,则填充范围为空.

5.4.3对数组进行排序

通过Arrays类的静态sort()方法可以实现对数组的排序.sort()方法提供了多种重载形式,可对任意类型的数组进行升序排序.
Arrays.sort(object)

5.4.4复制数组

1.copyOf(arr,intnewlength)方法
复制数组至指定长度
arr:要进行复制的数组
newlength:int型常量,指复制后的新数组的长度.如果新数组的长度大于数组arr的长度,则用0来填充(根据复制数组的类型来决定填充的值,整型数组用0填充,char型数组则使用null来填充);如果复制后的数组长度小于数组arr的长度,则会从数组arr的第一个元素开始截取至满足新数组长度为止.

2.copyOfRange(arr,int formIndex,int toIndex)
arr:要进行复制的数组对象.
formIndex:指定开始复制数组的索引位置.formIndex必须要在0至整个数组的长度之间.新数组包括索引是formIndex的元素.
toIndex:要复制范围的最后索引位置.可大于数组arr的长度.新数组不包括索引是toIndex的元素.

5.4.5数组查询

Arrays类的binarySearch()方法,可使用二分搜索法来搜索指定数组,以获得指定对象.该方法返回要搜索元素的索引值.
1.binarySearch(Object[] a,Object key)
a:要搜索的数组.
key要搜索的值
如果key包含在数组中,则返回搜索值的索引;否则返回-1或"-"(插入点).插入点是搜索键将要插入数组的那一点.即第一个大于此键的元素索引.


必须在进行此调用之前对数组进行排序(sort).如果没有对数组进行排序,则结果是不确定的.如果数组包含多个带有指定值的元素,则无法保证找到的是哪一个.

2.binarySearch(Object[] a,int fromIndex,int toIndex,Object key)
fromIndex:指定范围的开始处索引(包含)
toIndex:指定范围的结束处索引
在使用该方法之前同样要对数组进行排序,来获取准确的索引值.如果要搜索的元素key在指定的范围内,则返回搜索键的索引;否则返回-1或"-"(插入点).如果范围中的所有元素都小于指定的键,则为toIndex

5.5数组排序算法 5.5.1冒泡排序

冒泡排序算法是最常用的数组排序算法之一,它排序数组元素的过程总是将小数往前放,大数往后放.类似水中气泡往上升的动作,所以称作冒泡排序.
1.基本思想
冒泡排序的基本思想是对比相邻的元素值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把大的元素移动到数组后面(也就是交换两个元素的位置),这样较小的元素就像气泡一样从底部上升到顶部.
2.算法示例
冒泡算法由双层循环实现,其中外层循环用于控制排序轮数,一般为要排序的数组长度减-1次,因为最后一次循环只剩下一个数组元素,不需要对比,同时数组已经完成排序了.而内层循环主要用于对比数组中每个邻近元素的大小,以确定是否交换位置,对比和交换次数随排序轮数而减少.例如,一个拥有6个元素的数组的排序过程.

第一轮外层循环时把最大的元素值63移动到了最后面(相应地,比63小的元素向前移动,类似气泡上升),第二轮外层循环不再对比最后一个元素值63,因为它已经被确认为最大(不需要上升),应该放在最后,需要对比和移动的是其它剩余元素,这次将元素24移动到了63的前一个位置.其它循环将以此类推,继续完成排序任务.
3.算法实现

5.5.2直接选择排序

直接选择排序方法属于选择排序的一种,它的排序速度要比冒泡排序快一些,也是常用的排序算法.
1.基本思想
直接排序的基本思想是将指定排序位置与其他数组元素分别对比,如果满足条件就交换元素值.注意这里与冒牌排序的区别,不是交换相邻元素,而是把满足条件的元素与指定的排序位置交换.与冒泡排序相比,直接选择排序的交换次数要少很多,所以速度会快些.
2.算法示例
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序地放在已排好序的数列的最后,直到全部待排序的数据元素排完.

3.算法实现

5.5.3反转排序

顾名思义,反转排序就是以相反的顺序把原有数组的内容重新排序.
1.基本思想
把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,以此类推,直到把所有数组元素反转替换.
2.算法示例

3.算法实现

6.类和对象 6.1面向对象概述 6.1.1对象

对象是事物存在的实体,如人,书桌,计算机,高楼大厦等.通常会将对象划分为两个部分,即静态部分和动态部分.静态部分,顾名思义,就是不能动的部分,这个部分称为属性.

6.1.2类

类就是同一类事物的统称,如果将现实世界中的一个事物抽象成对象,类就是这类对象的统称,如鸟类,家禽类,人类等.类是世间事物的抽象称呼,而对象则是这个事物相对应的实体.
类是封装对象的属性和行为的载体,反过来说,具有相同属性和行为的一类实体称为类.在Java语言中,类中对象的行为是以方法的形式定义的,对象的属性是以成员变量的形式定义的,所以类包括对象的属性和方法.

6.1.3封装

面向对象程序设计具有以下特点:
1.封装性
2.继承性
3.多态性
封装是面向对象编程的核心思想.将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想.这种思想保证了类内部数据结构的完整性,应用该类的用户不能轻易地直接操作此数据结构,只能执行类允许公开的数据.这样就避免了外部操作对内部数据的影响,提高了程序的可维护性.

6.1.4继承

1.类与类之间同样具有关系,这种关系被称为关联.关联主要描述两个类之间的一般二元关系.两个类之间的关系有很多种,继承是关联中的一种.
2.继承性主要利用特定对象之间的共有属性.
3.设计软件时,使用继承的思想可以缩短软件开发的周期,复用那些已经定义好的类可以提高系统性能,减少系统在使用过程中出现错误的概率.

从图中可以看出,继承关系可以使用树形关系来表示,父类与子类存在一种层次关系.一个类处于继承体系中,它既可以是其他类的父类,为其他类提供属性和行为,也可以是其他类的子类,继承父类的属性和方法,如三角形既是图形类的子类也是等边三角形的父类.

6.1.5多态

1.父类和子类,其实将父类对象应用于子类的特征就是多态.以图形类来说明多态,每个图形都拥有绘制自己的能力,这个能力可以看做是该类具有的行为,如果将子类的对象统一看做是父类的实例对象,这样当绘制图形时,简单地调用父类也就是图形绘制图形的方法即可绘制任何图形,这就是多态的基本思想.
2.多态性允许以统一的风格编写程序,以处理种类繁多的已存在的类及相关类.该统一风格可以由父类来实现,根据父类统一风格的处理,可以实例化子类的对象.由于整个事件的处理都只依赖于父类的方法,所以日后只要维护和调整父类的方法即可,这样就降低了维护的难度,节省了时间.
3.在多态的机制中,父类通常会被定义为抽象类,在抽象类中给出一个方法的标准,而不给出实现的具体流程.实质上这个方法也是抽象的.
4.在多态的机制中,比抽象类更方便的方式是将抽象类定义为接口.由抽象方法组成的集合就是接口.如从不同五金商店买来的螺丝帽和螺丝钉,螺丝帽很轻松就能拧在螺丝钉上,可能螺丝帽和螺丝钉的厂家不同名单这两个物品可以轻易组合在一起,这是因为生产螺丝帽和螺丝钉的厂家都遵循着一个标准,这个标准在Java中就是接口.

6.2类 6.2.1成员变量

在Java中对象的属性也称为成员变量.

package my;

public class First {
	//成员变量
	int x = 45;
	String name;
	public void haha()
	{
		//局部变量
		int y = 520;
	}
}

6.2.2成员方法

在Java语言中使用成员方法对应于类对象的行为.

package my;

public class First {
	//成员变量
	int x = 45;
	String name;
	//成员方法
	public void haha()
	{
		//局部变量
		int y = 520;
	}
	//成员方法
	public void maPrint()
	{
		System.out.println(name);
	}
}

6.2.3权限修饰符

Java中的权限修饰符主要包括private,public和protected,这些修饰符控制着类和类的成员变量以及成员方法的访问.
1.如果一个类的成员变量或成员方法被修饰为private,则该成员变量只能在本类中被使用,在子类中是不可见的,并且对其他包的类也是不可见的.
2.如果访问权限设置为public,那么除了可以在本类中使用这些数据之外,还可以在子类和其他包的类中 使用.
3.如果一个类使用protected修饰符,那么只有本包内的该类的子类或其他类可以访问此类中的成员变量和方法.
总的来说,public和protected修饰的类可以被子类进行访问.如果子类和父类不在同一包内中,那么只有修饰符为public的类可以被子类进行方法.如果父类不允许通过继承产生的子类访问他的成员变量,那么必须使用private声明父类的这个成员变量.

6.2.4局部变量

如果在成员方法内定义一个变量,那么这个变量被称为局部变量.

package my;

public class First {
	//成员变量
	int x = 45;
	//成员方法
	public void haha()
	{
		//局部变量
		int y = 520;
	}
}

6.2.5局部变量的有效范围

可以将局部变量的有效范围称为变量的作用域,局部变量的有效范围从该变量的声明开始到该变量的结束为止.

6.2.6 this关键字
package my;

public class First {
	//成员变量
	String name;
	//成员方法
	public void setName()
	{
		//局部变量
		this.name = "lining";
	}
}

1.在Java语言中规定使用this关键字来代表本类对象的引用,this关键字被隐式地用于引用对象的成员变量和方法.
2.事实上,this引用的就是本类的一个对象.在局部变量或方法参数覆盖了成员变量时,就要添加this关键字明确引用的是类成员还是局部变量或方法参数.
3.this除了可以调用成员变量和成员方法外,还可以作为方法的返回值.

String name;
	public First getName() {
		return this;
	}
6.3类的构造方法

在类中除了成员方法外,还存在一种特殊类型的方法,那就是构造方法.构造方法是一个与类同名的方法,对象的创建就是通过构造方法完成的.每当实例化一个对象时,类都会自动调用构造方法.
特点:
1.构造方法没有返回值
2.构造方法的名称要与本类的名称相同
注意:
如果类中没有明确定义构造方法,编译器会自动创建一个不带参数的默认构造方法.

public class First {
	//成员变量
	String name;
	int id;
	public First()
	{
		this.name = "lining";
		this.id  = 520;
	}
}
6.4静态变量、常量和方法

由static修饰的变量,常量和方法被称作静态变量、常量和方法.静态成员属于类所有,区别于个别对象,可以在本类或其他类使用类名和"."运算符调用静态成员.

public class staticTest {
	//在类中定义静态常量
	final static double PI = 3.1415;
	//在类中定义静态变量
	static int id;
	//在类中定义静态方法
	public static void myMethod()
	{
		//调用静态常量
		System.out.println(staticTest.PI);
	}

}

当需要调用静态成员时,直接使用"类名.静态成员"形式调用即可.
静态数据与静态方法的作用通常是为了提供共享数据或方法,尽管使用这种方式调用静态成员比较方便,但静态成员同样遵循着public,private和protected修饰符的约束.
另外,在Java语言中对静态方法作出规定:
1.在静态方法中不可以使用this关键字
2.在静态方法中不可以直接调用非静态方法
3.不能将方法体内的局部变量声明为static的
在执行类时,希望先执行类的初始化动作,可以使用static定义一个静态区域.例如:

public class staticTest {
	static
	{
		//do something
	}

}

当这段代码被执行时,首先执行static块中的程序,并且只会执行一次.

6.5类的主方法

主方法是类的入口点,它定义了程序从何处开始;主方法提供对程序流向的控制,Java编译器通过主方法来执行程序.

public static void main(String[] args) {
		
		//方法体
	}

主方法的特性:
1.主方法是静态的,所以如果要直接在主方法中调用其他方法,则该方法必须也是静态的.
2.主方法没有返回值
3.主方法的形参为数组.其中args[0]~args[n]分别代表程序的第一个参数到第n个参数,可以使用args.length获取参数的个数

6.6对象

Java是一门面向对象的程序设计语言,对象是类抽象出来的,所有的问题都通过对象来处理.对象可以操作类的属性和方法解决相应的问题,所以了解对象的产生、操作和消亡是十分必要的.

6.6.1对象的创建

在Java语言中通过new操作符来创建对象.每实例化一个对象就会自动调用一次构造方法,实质上这个过程就是创建对象的过程.准确地说,可以在Java语言中使用new操作符调用构造方法创建对象

f对象被创建出来时,就是一个对象的引用,这个引用在内存中为对象分配了存储空间,当创建对象时,自动调用构造方法.也就是说,在Java语言中初始化与创建是绑定在一起的.
每个对象都是相互独立的,在内存中占据独立的内存地址,并且每个对象都具有自己生命周期,当一个对象的生命周期结束时,对象就变成垃圾,由java虚拟机自带的垃圾回收机制处理,不能再被使用.

6.6.2访问对象的属性和行为

用户使用new操作符创建一个对象后,可以使用"对象.类成员"来获取对象的属性和行为.对象的属性和行为在类中是通过类成员变量和成员方法的形式来表示的,所以当对象获取类成员时,也相应地获取了对象的属性和行为.

上述代码可以看到,由于使用h2.id = 2改变了静态成员的值,使用对象h1调用成员变量的值也为2,这正是id被声明为static的效果,因为在内存中两个对象同时指向同一块内存区域.

6.6.3对象的引用

在Java语言中尽管一切都可以看做对象,但真正的操作标识符实质上是一个引用.
语法:
类名 对象引用名称
如一个Book类的引用可以使用如下代码

Book book;

通常一个引用不一定需要有一个对象相关联.引用与对象相关联的语法如下:

Book book = new Book();

引用只是存放一个对象的内存地址,并非存放一个对象.严格来说,引用和对象是不同的,但是可以将这种区别忽略,可以简单地说book是Book类的一个对象,而事实上应该是book包含Book对象的一个引用.

6.6.4对象的比较

在Java语言中存在两种比较对象的方式,分别为"=="运算符和equals()方法.这两种方式有着本质区别.

从上述运行结果中可以看出, ==运算符和equals()方法比较的内存是不相同的,equals()方法是String类中的方法,它用于比较两个对象引用所指的内容是否相等;而后者比较的是两个对象引用的地址是否相等.由于s1和s2是两个不同的对象引用,两者在内存中的位置不同,而"String s3=s1;"语句将s1的引用赋给s3,所以s1和s3这两个对象引用是相等的.

6.6.5对象的销毁

每个对象都有生命周期,当对象的生命周期结束时,分配给该对象的内存地址需要被回收.在其他语言中,需要用户手动回收废弃的对象.Java拥有一套完整的垃圾回收机制,用户不必担心废弃的对象占用内存,垃圾回收器会自动回收无用却占用内存的资源.
对象被Java虚拟机视为垃圾的两种情况
1.对象引用超过其作用范围,这个对象将被视为垃圾.

2.将对象赋值为null

虽然垃圾回收机制已经很完善,但垃圾回收器只能回收那些由new操作符创建的对象.某些对象不是通过new操作符在内存中获取存储空间的,这种对象无法被垃圾回收机制所识别.在Java中提供了一个finalize()方法,这个方法是Object类的方法,它被声明为protected,用户可以在自己的类中定义这个方法.如果用户在类中定义了finalize()方法,在垃圾回收时会首先调用该方法,在下一次垃圾回收动作发生时,才真正回收被对象占用的内存.
**注意:**垃圾回收或finalize()方法并不保证一定会发生,如果Java虚拟机内存损耗殆尽,它将不会执行垃圾回收处理.由于垃圾回收不受人为控制,具体执行时间也不确定,所以finalize()方法也就无法执行.为此Java提供了System.gc()方法来强制启动垃圾回收器.

7.包装类 7.1Integer

java.lang包中的Integer类、Long类和Short类,可将基本类型int、long和short封装成一个类.这些类都是Number的子类,区别就是封装了不同的数据类型.
Integer类在对象中包装了一个基本类型int的值.该类的对象包含一个int类型的字段.此外,该类提供了多个方法,能在int类型和String类型之间互相装换,同时还提供了其他一些处理int类型时非常有用的常量和方法.

7.1.1构造方法

1.Integer(int number)
该方法以一个int型变量为参数来获取Integer对象.

Integer n = new Integer(520);

2.Integer(String str)

Integer n = new Integer("20");
7.1.2常用方法



**parseInt()**方法示例
该方法返回与调用该方法的数值字符串相应的整型(int)值.

**toString()**示例
toString()可将Integer对象转换为十进制字符串表示.toBinaryString(),toHexString()和toOctalString()方法分别将值转换为二进制、十六进制和八进制字符串

7.1.3常量

Integer类提供了以下4个常量
1.MAX_VALUE:表示int类型可取得最大值,即2^31-1
2.MIN_VALUE:表示int类型可取得最小值,即-2^31
3.SIZE:用来以二进制补码形式表示int值的位数
4.TYPE:表示基本类型int的Class实例

7.2Boolean

Boolean类将基本数据类型为boolean的值包装在一个对象中.一个Boolean类型的对象只包含一个类型为boolean的字段.此外,此类还为boolean和String的相互转换提供了许多方法,并提供了处理boolean时非常有用的其他一些常量和方法

7.2.1构造方法

Boolean(boolean value)

Boolean b = new Boolean(true);

Boolean(String str)

Boolean b = new Boolean("lining");

如果String参数不为null且在忽略大小写时等于true,则分配一个表示true值的Boolean对象,否则获得一个false值的Boolean对象.

7.2.2.常用方法


7.2.3.常量

1.TRUE:对应基值true的Boolean对象.
2/FALSE:对应基值false的Boolean对象
3.TYPE:基本类型boolean的Class对象.

7.3Byte

Byte类将基本类型为byte的值包装在一个对象中.一个Byte类型的对象只包含一个类型为byte的字段.此外,该类还为byte和String的相互转换提供了方法,并提供了其他一些处理byte时非常有用的常量和方法.

7.3.1构造方法

1.Byte(byte value)
通过这种方法创建的Byte对象,可表示指定的byte值

Byte b = new Byte((byte) 20);

2.Byte(String str)

7.3.2常用方法

7.3.3常量

1.MAX_VALUE:表示byte类型可取得最大值
2.MIN_VALUE:表示byte类型可取得最小值
3.SIZE:用来以二进制补码形式表示byte值的位数
4.TYPE:表示基本类型byte的Class实例

7.4Character

Character类在对象中包装一个基本类型为插入的值.一个Character类型的对象包含类型为插入的单个字段.该类提供了几种方法以确定字符的类别,并将字符从大写转换成小写,反之亦然.

7.4.1构造方法
Character c = new Character('s');
7.4.2常用方法


7.4.3常量

1.CONNECTOR_PUNCTUATION:返回byte值,表示Unicode规范中的常规类别"Pc"
2.UNASSIGNED:返回byte值,表示Unicode规范中的常规类别"Cn"
3.TITLECASE_LETTER:返回byte值,表示Unicode规范中的常规类别"Lt".

7.5Double

Double和Float包装类是对double、float基本类型的封装,他们都是Number类的子类,有都是对小数进行操作,所以常用方法基本相同.
Double类在对象中包装一个基本类型为double的值.每个Double类的对象都包含一个double类型的字段.

7.5.1构造方法

1.Double(double value):基于double参数创建Double对象
2.Double(String str):构造一个新分配的Double对象,表示用字符串表示的double类型的浮点值.

7.5.2常用方法

7.5.3常量

1.MAX_EXPONENT:返回int值,表示有限double变量可能具有的最大指数
2.MIN_EXPONENT:返回int值,表示标准化double变量可能具有的最小指数
3.NEGATIVE_INFINITY:返回double值,表示保存double类型的负无穷大值的常量.
4.POSITIVE_INFINITY:返回double值,表示保存double类型的正无穷大值的常量.

7.6Number

抽象类Number是BigDecimal、BigInter、Byte、Double、Float、Integer、Long、和Short类的父类,Number的子类必须提供将表示的数值转换为byte,double,float,int,long和short的方法


Number类的方法分别被Number的各子类所实现,也就是说,在Number类的所有子类中都包含以上这几种方法.
2022.1.23.12.19

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/715548.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号