面向对象的思想
面向对象与面向过程的比较:
都是编程思想,面向过程是面向对象的基础,面向对象是基于面向过程的。
面向过程: 更强调解决问题的步骤,更强调解决问题的方式,更强调的是方法。编程思路:自顶向下,不断分析。
面向对象: 更强调的是解决问题的主体,谁来解决这个问题,强调的是数据,更强调的是对象。编程思路:自底向上,不断拼装。
类和对象
类: 类型,对具体事物的抽像,就是一组属性和行为的集合
属性: 就是Java中的一些变量,常量。
行为: 就是Java中的成员方法
抽象: 抽取出事物共同的特征,形成一个概念
对象: 事物的具体体现
对象的创建与使用
创建格式:
类名 对象名 = new 类名();
访问属性:
对象名.属性名
对象名.属性名=属性值
访问方法:
对象名.方法名();
创建对象的步骤:
1.将要创建的对象所属的类型加载到方法区,形成.class的字节码文件
2.在栈内存中创建一个引用,用于存储堆内存中对象的地址
3.在堆内存中开辟空间,给各个成员变量分配内存
4.给对象中的成员变量进行默认初始化赋值
5.将对象的地址,赋给堆内存中的引用
一个对象的内存图:
面向对象其他内容
成员变量与局部变量的比较:
定义位置不同:
局部变量定义在方法中,或者方法的声名上
成员变量定义在类中放法外
内存空间不同:
局部变量存储在栈中
成员变量,属于对象,存储在堆内存中
初始化状态不同:
局部变量没有默认的初始化,必须线赋值再使用
成员变量有默认的初始化值
封装性
所谓封装,就是将客观事物封装成抽象的类,并且类可以把数据和方法让可信的类或者对象进行操作,对不可信的类或者对象进行隐藏。类就是封装数据和操作这些数据代码的逻辑实体。在一个类的内部,某些属性和方法是私有的,不能被外界所访问。通过这种方式,对象对内部数据进行了不同级别的访问控制,就避免了程序中的无关部分的意外改变或错误改变了对象的私有部分。
通俗理解: 将事物的属性和方法隐藏起来,对外提供公共的访问方式
封装的优点:
- 隐藏了事物的属性和方法
- 提高了代码的复用性
- 提高了安全性
通常使用private进行封装
封装后只能只能本类访问,非本类访问需要调用set() get() 方法
代码示例
public class Person{
private String name;
private int age;
private char sex;
//添加get set 方法
public String getName() {
return name;
}
// 实现间接赋值
public void setName(String name1) {
name = name1;
}
// 实现给age属性间接赋值
public void setAge(int age1) {
if(age1<0) {
age=18;
}else {
age = age1;
}
}
public int getAge() {
return age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
}
******************************************
//get set 方法间接访问
public class Test{
public static void main(string[] args){
person ps = new Person();
ps.setName("张三");
String name=ps.getName();
System.out.println(name);
}
}
继承性
继承有这样一种能力,就是能使用现有的类的所有功能,并无须重新编写原来的这些类的基础上对这些功能进行扩展。通过继承创建的新类称为子类或派生类,被继承的称为基类。继承有两种,一种是实现继承,另外一种是接口继承。实现继承可以直接使用基类的属性和方法而无需额外编码,接口继承是指使用属性和方法的名称,但是子必须提供实现的能力。
父类: 基类 超类
子类: 派生类
所有类都直接或者间接继承了Object类
Java中只支持单继承,一个类只能有一个直接父类,可以有多个间接父类。
是不是任意两个类都可以满足继承关系呢?
A 类 is a B类 这句话成立 则 A类可以继承B类,反之不成立
A类满足B类具有的全部特征才可以继承。
优点:
继承可以提高代码的复用性。
继承是多态的前提
继承情况下子类可以从父类那儿拿到什么东西?
可以继承属性:
如果父类的属性使用如下访问修饰符修饰: 则可以继承到
- public 同一个项目 不同项目都可以继承到
- 默认 子类和父类只能在同一个包中
- protected 同一个包下 同一个项目的不同包下也可以继承到
- 父类中private修饰的 属性,子类绝对继承不到
可以继承方法:
如果父类的属性使用如下访问修饰符修饰: 则可以继承到
- public 同一个项目 不同项目都可以继承到
- 默认 子类和父类只能在同一个包中
- protected 同一个包下 同一个项目的不同包下也可以继承到
- 父类中private修饰的 属性,子类绝对继承不到
- 不能继承构造方法 可以调用。
继承关系下变量的关系:
- 如果父类有一个属性,子类也有一个属性,这两个属性不同名,那么子类既可以访问父类,也可以访问子类的。
- 如果父类和子类有一个同名的属性,那么在子类中会根据就近原则,进行访问。先在本方法找,如果没有,在本类找,如果本来也没有就在父类找,一直找到Object类。如果也没有,则报错。
继承关系下创建对象的情况:
- 将子类和父类的字节码文件加载进方法区。
- 在堆中开辟空间存放子类的属性,在子类对象靠前的位置上存放父类的属性
- 完成对父类属性的赋值 先默认赋值 再显示赋值 再构造方法赋值
- 完成对子类属性的赋值 先默认赋值 再显示赋值 最后在构造方法赋值
- 将堆中的地址放到栈中变量中
继承关系下成员方法的情况:
- 当子类调用方法时,会首先从当前类找,如果找不见,则去父类找,父类如果找不见,直到找到object类,仍然找不见,然后会报编译错误
- 如果子类和父类有同名的方法呢?此时子类的方法需要重写父类的方法。
练习
轿车:
属性
租赁的天数
车牌号
汽车品牌
方法:
计算租金
客车:
属性:
租赁的天数
车牌号
汽车品牌
座位数
方法:
计算租金
Car父类:
属性
租赁的天数
车牌号
汽车品牌
方法:
计算租金
父类:
public class Car {
private String no;//汽车车牌
private String brand;//汽车品牌
public Car() {
//无参构造
}
public Car(String no,String brand) {
this.no=no;
this.brand=brand;
}
}
客车类继承车类:
public class Keche extends Car {
private int seatCount;// 座位数
public Keche() {
}
public Keche(String no, String brand, int seatCount) {
super(no, brand);
this.seatCount = seatCount;
}
/**
* 计算客车租赁价
*/
public int calRent(int days) {
if (seatCount <= 16) {
return days * 800;
} else {
return days * 1500;
}
}
}
轿车类继承车类:
public class Qiaoche extends Car{
private String type;// 汽车型号
public Qiaoche() {
}
public Qiaoche(String no, String brand, String type) {
super(no, brand);
this.type = type;
}
/**
* 计算轿车租赁价
*/
public int calRent(int days) {
if ("1".equals(type)) {// 代表550i
return days * 500;
} else if ("2".equals(type)) {// 2代表商务舱GL8
return 600 * days;
} else {
return 300 * days;
}
}
}
测试类(主类)
import java.util.Scanner;
public class dome1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Qiaoche qiao;
Keche ke;
String no,brand;
int rent,seatCount;
System.out.println("欢迎进入汽车租赁系统");
System.out.println("请选择你需要租赁的车型(1.轿车2.客车):");
int type=input.nextInt();
if(type==1) {
System.out.println("请选择你需要的车型(1.宝马2.别克)");
String chexing =input.next();
if(chexing.contentEquals("宝马")) {
System.out.println("请输入你需要租的天数");
int tianshu=input.nextInt();
}else {
System.out.println("请输入别克车品牌(1.商务2.梦林大道)");
String pinpai=input.next();
if(pinpai.equals("商务")) {
System.out.println("请输入你需要租的天数");
int tianshu=input.nextInt();
no="京BK5543";
System.out.println("分配给你的汽车车牌是:"+no);
qiao=new Qiaoche(no,chexing,pinpai);
rent=qiao.calRent(tianshu);
System.out.println("租金是:"+rent);
}else {
System.out.println("请输入你需要租的天数");
int tianshu=input.nextInt();
no="京BK5543";
System.out.println("分配给你的汽车车牌是:"+no);
qiao=new Qiaoche(no,chexing,pinpai);
rent=qiao.calRent(tianshu);
System.out.println("租金是:"+rent);
}
}
}else {
System.out.println("请输入天数");
int tianshu=input.nextInt();
System.out.print("请输入要租赁的客车品牌(1、金杯 2、金龙):");
brand=input.next();
System.out.print("请输入客车的座位数:");
seatCount=input.nextInt();
no="京AU8769";//简单起见,直接指定汽车牌号
System.out.println("分配给您的汽车牌号是:"+no);
ke=new Keche(no,brand,seatCount);
rent=ke.calRent(tianshu);
System.out.println("租金是:"+rent);
}
}
}
多态性
所谓多态就是对一个实例的相同方法在不同的情形下有不同的表现形式。多态机制使得不同内部结构的对象可以共享相同的外部接口,这就意味着,虽然不同的类的内部操作不同,但可以通过一个公共的类,它们可以通过相同的方式予以调用
概述: 针对同一个行为,不同的人有不同的表现形态
多态的前提条件:
- 继承父子之间
- 方法的重写(子类重写父类的方法)
- 父类类型指向子类对象
练习:
父类:
public class Father {
String name;
public void eat(String food) {
System.out.println("吃"+food);
}
public void wan() {
}
}
中国客人类:
public class Xiao extends Father{
public void wan() {
System.out.println("练太极");
}
}
外国客人类:
public class Yue extends Father {
public void wan() {
System.out.println("打橄榄球");
}
}
主人类:
public class master {
String name;
public void peiwan(Father f) {
f.wan();
}
}
测试类:
public class test {
public static void main(String[] args) {
Scanner input= new Scanner(System.in);
Father f=new Father();
master m= new master();
m.name="牛犇";
Xiao ch=new Xiao();
ch.name="王小强";
System.out.println(m.name+"陪"+ch.name+":");
ch.eat("四川菜");
m.peiwan(ch);
Yue yue=new Yue();
yue.name="约翰";
System.out.println(m.name+"陪"+yue.name+":");
yue.eat("披萨");
m.peiwan(yue);
}
}
构造方法
- 当我们创建对象时,jdk会默认调用我们Person类的构造方法。
- 构造方法是用来创建对象的。
- 当我们没有给类写构造方法时,jdk会给我们添加一个默认的构造方法。但你一旦你写了构造方法,jdk都不再给你提供构造方法。
- 定义语法:
public 类名(){
}
public 类名(String name,int age){
this.name=name;
this.age=age;
}
特点:
- 使用public修饰
- 方法名必须和类名一致
- 无返回值
- 定义位置在类中 方法外
- 调用时机:
创建对象时,由jdk来调用类的构造方法。
关键字
this和super关键字
this代表的是本类的对象
本类的属性 也可以访问父类的属性
本类的方法 也可以访问父类的方法
本类的构造方法
super:本类的父类对象。
本类中父类的属性
本类中父类的方法
父类的构造方法
static关键字
概念
static 静态的 静止的 固定的
使用场合
针对类的某个属性,所有对象的值都一样,此时我们没有必要在每个对象的堆空间中都存储一份,我们可以将该属性值存储在类的字节码的静态区中。
static能修饰哪些东西:
属性(成员变量):
- static只能修饰成员变量,不能修饰局部变量
- static修饰的成员变量属于类,所有对象共享一份。
- static修饰的成员变量 可以通过
类名.属性名访问和修改(常用)
对象名.属性名访问和修改
方法:
4. static修饰的方法属于类,所有对象共享一份
5. static修饰方法,我们可以通过类名.方法名去访问,也可以通过对象名.方法名去访问。
6. 在静态方法中只能访问静态属性和静态方法
7. 在静态方法中不能出现this关键字
8. 在静态方法中只能有 静态方法 静态属性 局部变量
静态方法中为什么只能访问静态属性和静态方法呢?
因为静态方法和静态属性属于类,可以在没有对象的情况下,直接通过类名访问,而非静态属性和方法属于对象,那么没有对象,这些非静态属性和方法压根不存在。
补充说明:
静态方法存在 方法区的字节码文件的静态区中。
当你加载字节码文件进入内存时,会同时将该类的静态属性和方法一起加载进静态区。
代码块
static {
className="java001";
}
静态的应用
创建工具类,完成对数组的基本操作的编写。
/**
* 工具类,完成数组的一些基本操作
* @author Administrator
*
*/
public class ArrayTools {
// 遍历数组
public static void arrayOutPut(int[] nums) {
for(int i=0;i<nums.length;i++) {
System.out.println(nums[i]);
}
}
// 求最大值
public static int getArrayMax(int[] nums) {
int max = nums[0];
for(int i=0;i<nums.length;i++) {
if(max<nums[i]) {
max=nums[i];
}
}
return max;
}
// 求最小值
public static int getArrayMin(int[] nums) {
int min = nums[0];
for(int i=0;i<nums.length;i++) {
if(min>nums[i]) {
min=nums[i];
}
}
return min;
}
生成javadoc文档:
1.使用文档注释来对类 方法 参数进行说明
使用javadoc命令生成
final关键字
final 可以修饰 变量 方法 类
Final修饰变量:
那么该变量就称为常量,它可以修饰
局部变量: 第一次赋值是多少就是多少,程序不能修改常量的值。
一般情况下,常量名字都是大写
成员变量: 一旦成员变量用final修饰了,则jdk不会再给你赋初始值,需要手动给成员变量赋值。
final修饰方法:
Final修饰的方法变成最终方法,它不允许被重写,但是可以重载
final修饰的类:
Final修饰的类不允许被继承,不允许有后代
instanceof关键字
作用: 判断一个对像到底是哪个类的实例
代码块
一段代码用一个{}包起来,就叫代码块,但是根据它所在的位置不同,存在的时间不同,我们将其分为:
1.局部代码块
2.构造代码块
3.静态代码块
4.同步代码块
局部代码块
定义在方法内的代码块,就叫局部代码块,它随着方法的调用开始,随着方法的结束调用就结束了。
特点: 在局部代码块中定义的变量,叫局部变量,它的使用范围仅限定义它的{},离开{}它就从内存消失,不能再使用。
构造代码块
位置: 类中方法外
用途: 用来给类的属性完成一些初始化工作
执行时机: 它在构造方法前执行,每创建一次对象,就执行一次构造代码块。所以我一般把所有构造方法都写的代码,放在构造代码块中,减少代码的冗余。
/**
* 狗类
* @author Administrator
*
*/
public class Dog {
String name;// 名字
String sex;//性别
{
sex="男";
System.out.println("我是构造代码块");
}
public Dog() {
System.out.println("我是无参构造方法");
}
public Dog(String name) {
this.name =name;
System.out.println("我是带参数的构造方法");
}
静态代码块
位置: 类中方法外
语法: static{
}
所有用static修饰的东西,它都属于类,和对象无关。
执行时机: 将类的字节码文件加载进内存时,它就会执行,而且只执行这一次。静态代码块优先于静态属性和方法的执行。
静态属性能写啥:
只能给静态属性赋值
只能调用静态方法
static {
//name="张三";
System.out.println("我是静态代码块");
}
同步代码块
位置: 写在方法内
语法:
synchronized{
for(int i=10;i<100;i++){
输出i
}
}
保证一段代码,在同一个时间只能让一个线程去执行。
总结
当一个类中既有构造代码块 静态代码块 构造方法 执行顺序为:
静态代码块->构造代码块->构造方法
父子关系下,这几个代码块的执行顺序:
代码:
public class Father {
static int i;
static {
i=10;
System.out.println("我是父类的静态代码快");
}
{
i=11;
System.out.println("我是父类的构造代码块");
}
public Father() {
i=12;
System.out.println("我是父类的构造方法");
}
public class Son extends Father {
static {
System.out.println("我是子类的静态代码块");
}
{
System.out.println("我是子类的构造代码块");
}
public Son() {
System.out.println("我是子类的构造方法");
}
}
对象数组
抽象类
抽象类
语法:
Public abstract class Pet{
}
特点:
- 使用abstract修饰
- 抽象类不能被实例化(不能被new)
- 抽象类中可以有普通方法,也可以有抽象方法
- 一般父类都是抽象类
- 抽象类中可以定义成员变量
注意:
- 抽象类是为了让子类来继承的,它存在的价值就在此处。如果子类没有将父类中的所有抽象方法都重写,则子类也必须是一个抽象类。
- abstract和final不能同时修饰一个类,也不能同时修饰一个方法。
抽象方法
语法:
public abstract void show();
特点:
- 使用abstratc修饰
- 没有方法体
- 一般我们会在父类中定义抽象方法,由子类去重写该方法
- 抽象方法只能在抽象类中
接口
概述
- 接口代表了一种能力或者一种标准。
- Java中是单继承的,一个类只能有一个直接父类,接口的出现是为了间接实现多继承。
判断一个类 能否继承另外一个类?
A is a B 如果满足 则 说明A可以继承B
判断一个类能否 实现某个接口?
A has a C 如果满足 则说明A可以实现C这个接口
语法:
public interfacte Ipet{
只能写
1.抽象方法
2.静态常量
}
案例:
防盗门可以开门 关门 开锁 关锁
门 是个类
锁 是个接口
/**
* 门
* @author Administrator
*
*/
public abstract class Door {
/**
* 开门
*/
public abstract void openDoor();
/**
* 关门
*/
public abstract void closeDoor();
}
/**
* 锁接口
* @author Administrator
*
*/
public interface Suo {
/**
* 开锁
*/
void openSuo();
/**
* 上锁
*/
void closeSuo();
}
/**
* 防盗门
* @author Administrator
*
*/
public class FangDoor extends Door implements Suo{
@Override
public void openDoor() {
// TODO Auto-generated method stub
System.out.println("开门");
}
@Override
public void closeDoor() {
// TODO Auto-generated method stub
System.out.println("关门");
}
@Override
public void openSuo() {
// TODO Auto-generated method stub
System.out.println("开锁");
}
@Override
public void closeSuo() {
// TODO Auto-generated method stub
System.out.println("上锁");
}
}
测试类:
FangDoor fd =new FangDoor();
fd.openSuo();
fd.openDoor();
fd.closeDoor();
fd.closeSuo();
实现语法:
Public class Pet implements Idoor,Ifoor,Iroop{
}
注意: Pet如果能将Idoor,Ifoor,Iroop中的所有方法都重写,则Pet类是一个普通类。
否则只能是一个抽象类
抽象类和接口有什么区别?
- 抽象类中可以写抽象方法 普通方法 成员变量 常量
- 接口只能写抽象方法和静态常量
- 抽象类和接口都不能实例化,都需要子类去继承或者实现。
- 一个类只能继承一个抽象类,但是可以实现多个接口
匿名对象
匿名内部类
概述:
它属于局部内部类,它定义在方法中
匿名内部类的使用前提:
1.抽象类
2.接口
匿名内部类可以理解为抽象类或者接口的子类(实现类)
语法:
new 父类或者接口() {
// 对父类或者接口中方法的重写
public void show() {
System.out.println("哈哈");
}
public void to_Hospital() {
System.out.println("带猫去看病");
}
};
实际业务中:
当一个父类只创建一次对象时,我们可以使用匿名内部类,当你要创建多个对象时,还是去专门定义一个子类,然后创建子类对象。
匿名内部类:
编译之后会按照编写顺序生成class文件,文件名是外部类$1 外部类$2
有名字的内部类:
名字为 外部类名$内部类名
object类
概述:
- 所有类的父类
- 它有构造方法,所以可以new对象。
- Object o =new Object();
toString()
未重写该方法之前,通过对象调用,输出的是对象的地址。我们会将该方法重写,使得输出该对象的属性值。
equals()
equals比较的是两个对象在堆中的地址是否一样。
比较相等:
==:基本数据类型(byte short int double float long boolean char)的比较相等。如果引用数据类型使用==比较,它比较的是两个对象在堆中的地址是否一致。
Equals: 只能用于引用数据类型比较,而且我们一般需要将equals方法进行重写,使得其比较两个对象的属性值是否一致。
String类
Scanner类
概述:
扫描仪类:
构造方法:
Scanner(InputStream source)
构造一个新的 Scanner ,产生从指定输入流扫描的值。
Scanner(File source)
构造一个新的 Scanner ,产生从指定文件扫描的值。
常用的成员方法:
nextInt()从键盘输入整数
next() 从键盘输入字符串
nextDouble()从键盘输入小数
nextFloat() 从键盘输入小数
next().charAt(0) 从键盘输入字符
nextShort() 从键盘输入整数
nextByte() 从键盘输入整数
nextLine() 从键盘输入字符串
math类
System类
概述:
String类是一个不可修改值的类
构造方法:
String()
String(bye[] bytes)
String(bytes[] bytes,int offset,int length)
String str=“张三”;
str=“李四”;
// 以下代码在内存中有几个对象
// 2个对象 1. str对象 2.张三也被认为是一个对象
String str=new String(“张三”);
str=new String(“李四”);
代码:
// byte[] nums= {-10,-20,-30,-40,125};
// // 从下标为2的地方开始,取2个字节来转成字符串
// String str2 = new String(nums,2,2);
// System.out.println(str2.toString());
判断类的成员方法: 返回值是布尔类型
- equals(Object obj):判断调⽤者和参数对象描述的字符串内容是否相同,重写的Object中的equals
- equalsIgnoreCase(String otherStr):忽略⼤⼩写判断两个字符串内容是否相同
- contains(String str):判断调⽤者是否包含了str这个⼦串
- startsWith(String prefix):判断调⽤者是否以prefix开头
- endsWith(String suffix):判断调⽤者是否以suffix结尾
- isEmpty():判断调⽤者是否是空串
代码:
String str="756752122@qq.com";
String str1="Hello";
System.out.println(str.equals(str1));
System.out.println(str.equalsIgnoreCase(str1));
System.out.println(str.contains("qq"));
System.out.println(str.startsWith("@"));
System.out.println(str.endsWith("m"));
System.out.println(str.isEmpty());
String类常用方法二(获取值):
- length():获取字符串字符的个数
- charAt(int index):返回调⽤者字符串中索引为index的字符(和length⽅法结合之后可以遍历
字符串) - substring(int beginIndex):获取⼀个字符串,内容是从当前字符串的beginIndex索引开始
- substring(int beginIndex, int endIndex):获取⼀个指定索引范围的⼦串
注意事项:1、包含头不包含尾,返回的结果中,不包含endIndex索引指向的字符;2、所有的⽅法都⽆法修改字符串对象本身,⼀般都是返回⼀个新的字符串对象
indexOf家族:
indexOf(int ch):返回ch字符在当前调⽤者字符串中,第⼀次出现的索引.
indexOf(int ch, int fromIndex):从fromIndex索引开始寻找,找到ch字符在当前字符串中第
⼀次出现的索引.
indexOf(String str):返回的是str这个字符串在调⽤者字符串中第⼀次出现的索引.
indexOf(String str, int fromIndex):从fromIndex索引开始寻找,找到str字符串在当前字
符串中第⼀次出现的索引(注意:⽆论从哪个位置开始找,所有字符的索引都不会变化)
lastIndexOf家族:
和IndexOf基本⼀样,只不过是从后往前找,所有字符和字符串的索引也都不会发⽣变化
代码:
String str="756752122";
// 获取长度
// System.out.println(str.length());
// // 从str中获取一个子串 从下标为1的地方开始截取直到最后一位
// String sy=str.substring(1);
// // 从下标为1的地方开始截取到下标为6的地方结束
// String sy1 = str.substring(1, 7);
// System.out.println(sy1);
// 在一个字符串中查找某个字符或者子串的下标
// 从下标为0的地方开始找 如果存在,就是找见的第一个位置的下标,如果找不见则返回-1
// int sj=str.indexOf("5");
// // 从下标为3的地方开始找
// int sj1 = str.indexOf("5", 3);
// System.out.println(sj);
int last=str.lastIndexOf("5",3);
System.out.println(last);
// String str="756752122@qq.com";
// 如何判断一个字符串中存放的是正常的邮箱
// @ . @在.前面
// 长度不能低于10位
常用方法三(转化以及其他常用方法):
- byte[] getBytes():将当前字符串,转成字节数组
- char[] toCharArray():将当前的字符串,转成字符数组
- toUpperCase():将当前的字符串,转成全⼤写形式
- toLowerCase():将当前的字符串,转成全⼩写形式
String str=“张三ABCABCABCBA”;
// 将字符串转化成字节数组
// byte[] nums=str.getBytes();
// for(int i=0;i<nums.length;i++) {
// System.out.println(nums[i]);
// }
// System.out.println("***********");
// // 将字符串转化成字符数组
// char[] num1=str.toCharArray();
// for(int i=0;i<num1.length;i++) {
// System.out.println(num1[i]);
// }
// // 将字符串中的英文字母转成大写
// String str1=str.toUpperCase();
//
// // 将字符串中的英文字母转成小写
// String str2=str.toLowerCase();
// System.out.println(str2);
// 替换
// String str3=str.replace(‘A’, ‘a’);
// //str.replaceAll("\w", “123”);
// System.out.println(str3);
//
// String sh =“枯藤老树昏鸦,小桥流水人家,古道西风瘦马,夕阳西下,断肠人在天涯健康李老师江苏考生”;
// // 分割 根据,分割成子串
// String[] mk=sh.split(",");
// // 使用-将mk数组中的元素拼接起来
// String ll=String.join("-", mk);
// System.out.println(ll);
// trim 去掉字符串前后的空格
// 我是 中国人
String qq=" 你好 我是中国人 ";
String dd=qq.trim();
System.out.println(dd);