String字符串
String是一个类,属于数据类型中的引用类型。
Java的一切使用""引起来的内容,都是这个类的实例,称为字符串对象。
字符串在定义后,制不可改变,是一个创两,实际是一个字符数组。
String类使用时注意:
如果要频繁改动String类型变量的值,会创建很多字符串对象,效率低
如果要频繁改动字符串,使用StringBuilder或StringBuffer类
如何创建字符串对象
使用""赋值创建
String str="abc";
通过构造方法创建:
常用构造方法 | 说明 |
String() | 创建一个空白字符串对象即"" |
String(String str) | 创建一个指定字符串对象 |
String(char[] list) | 创建一个知道你字符数组的字符串对象 |
String(byte[] bytes,String charsetName) | 按指定的编码格式创建一个指定字节数组的字符串对象 |
不同方式创建字符串的过程
使用赋值的形式创建
使用构造方法String(String str)创建
String str=new String("ab");
使用+拼接""和new 出来的字符串对象创建
String str2 = "a" + new String("b");
总结
在使用字符串时,字符串是对象,如果要比较其值是否相同,不能使用==,因为==判断的是内存地址
所以在比较字符串是否相同时,要是用String类重写的equals方法进行判断。
String类中equals重写的原理:判断是否为同一字符串,在判断是否是字符串类型,再将两个字符串转换为字节数组,逐一比较字节数组中的内容,全部一致,返回true
调节equals方法时,通常将已知非空字符串作为调用者。
字符串String类中的常用方法:
方法名 | 返回值 | 作用 |
length() | int | 得到字符串长度 |
toLowerCase(Upper) | String | 转换为小写(大写) |
trim() | String | 去除字符串首尾的全部空格 |
isEmpty() | boolean | 判断字符串长度是否为0 |
getBytes() | byte[] | 转换为字节数组 |
toCharArray() | char[] | 转换为字符数组 |
equals(String str) | boolean | 判断两个字符串是否相同 |
charAt(int index) | char | 得到某个索引上的字符 |
indexOf(String str) | int | 得到某个字符串第一次出现的索引,不存在返回-1 |
lastIndexOf | int | 得到某个字符串最后一次出现的索引,不存在返回-1 |
contains(String str) | boolean | 判断是否存在某个字符串 |
substring(int index) | String | 从索引index开始截取字符串至末尾 |
substring(int begin,int end) | String | 截取[begin,end]之间的字符串 |
split(String regex) | String[] | 根据字符串或正则表达式切分原字符串 |
String.valueOf(参数) | String | 将参数转换为字符串,参数可以是任何数据,通常用于原始类型转换为字符串 |
可变字符串
String字符串对象是一个常量,在定义后,值不可改变。如果要对String类的对象频繁更新时,就会不停创建新对象,不停引用给同一个变量。所以引出可变字符串。
StringBuilder:
用于表示可变字符串的一个类,是非线程安全的,在单线程环境下使用,效率更高
StringBuffer:
用于表示可变字符串的一个类,是线程安全的,在多线程环境下使用
StringBuilder和StringBuffer中的方法都一致,但StringBuffer中的方法使用了synchronized关键字修饰,表示是一个同步方法,在多线程环境下爱不会出现问题。
构造方法:
常用构造方法 | 作用 |
StringBuilder() | 创建一个大小为16的字节数组,表示一个空白字符串 |
StringBuilder(int capacity) | 创建一个指定大小的字节数组,表示一个空白字符串 |
StringBuilder(String str) | 创建一个str的长度+16大小的字节数组,表示str这个字符串 |
常用方法:
常用方法 | 作用 |
append(Object obj) | 将任意数组添加到原可变字符串末尾 |
delete(int start,int end) | 删除[start,end)范围内的字符 |
deleteCharAt(int index) | 删除index索引上的字符 |
insert(int index,Object obj) | 将obj添加到index上 |
replace(int start,int end,String str) | 将[start,end)范围内的字符替换为str |
reverse() | 反转字符串 |
注意:
String类中的所有方法调用后,都会创建一个新的String对象,即原本的String字符串不会改变。
StringBuilder类中的所有方法都是在操作同一个字符串对象,每次调用方法,都会让源字符串发生变化。
StringBuilder类中没有重写equals方法,所以判断两个可变字符串对象是否相同时,如果调用equals方法,实际调用的时Object类中为重写的方法。即==判断,所以判断可变字符串是否相等,需要将其转换为String对象再调用equals方法。
可变字符串与String之间的转换
String转换为可变字符串
String str="hello";//使用构造方法将String对象转换为StringBuilder对象
StringBuilder sb=new StringBuilder(str);
可变字符串转换为String(任意类型对象转换为String)
String.valueOf(Object obj)方法:
StringBuilder sb=new StringBuilder("hello");
String str=String.valueOf(sb);
toString()方法
StringBuilder sb=new StringBuilder("hello")
String str=sb.toString();
拼接空字符串
StringBuilder sb=new StringBuilder("hello")
String str=sb+"";
可变字符串相关面试题:
比较String StringBuilder StringBuffer的区别
相同:这三个类都可以表示字符串,都提供一些操作字符串的方法。
这三个类中有相同的方法,如charAt(),indexOf()
这三个类都是被final修饰的类,不能被继承
不同:
String定义的字符串是一个常量,可变字符串定义的字符串是一个变量
String类中的方法调用后,不会改变原本字符串的值,可变字符串的方法调用后,会改变原字符串的值
StringBuilder是非线程的可变字符串类,StringBuffer是线程安全的可变字符串类,其中的方法被sychronized修饰
总结
在频繁操作同一个字符串时,一定使用StringBuilder或StringBuffer对象
操作不经常改动的字符串,使用者三个类中相应的方法处理。
System类
这个类包含了一些系统相关的信息和一些方法。其中的属性和方法都是静态的。这类不能创建对象,因为他的构造方法是私有的。
常用的方法和属性
常用方法和属性 | |
System.out | 获取标准输出流对象,用于打印信息 |
System.in | 获取标准输入流对象,用于获取输入的信息 |
System.err | 获取错误输出流对象,用于打印异常信息 |
System.exit(int statues) | 终止虚拟机运行,参数0表示正常终止 |
System.currentTimeMills() | 获取从1970至今多少毫秒,返回值为long,通常称为时间戳 |
System.arraycopy(原数组,原数组的起始位置,目标数组,目标数组的起始位置,要复制的元素数量) | 将原数组中指定数量的元素复制到新数组中 |
Runtime类:
Runtime类的对象,表示程序运行时对象(程序运行环境对象)
包含了程序运行环境的相关的信息。常用于获取运行环境信息(如虚拟机信息)
特点:这个类不是抽象类,但因为构造方法私有,所以不能创建对象
这个类提供一个静态方法getRuntime(),因此可以获得一个Runtime类的对象
这种方法可以保证该类只能创建一个对象,时java中的一种设计模式:单例模式。
public class Runtime{
//定义了一个私有的静态成员,创建一个当前类的对象
private static Runtime currentRuntime = new Runtime();
//将构造方法私有,无法在外创建对象
private Runtime();
//定义了一个公开的静态方法,用于获取创建的唯一的当前类的对象
public static Runtime getRuntime(){
return currentRuntime;
}
}
Date类
用于表示日期时间的类,位于java.util包下
构造方法
Date() | 创建当前时间对应的日期对象 |
Date(long I) | 创建指定瞬间对应的日期对象 |
Date(int year,int month,int date) | 根据年月日创建日期对象 |
常用方法:
getTime() | 得到Date对应对象的毫秒数 |
after(Date when) | 判断参数是否在调用日期之后 |
before(Date when) | 判断参数是否在调用日期之前 |
SimpleDateFormat类
用于格式化日期的类
构造方法
SimpleDateFormat(String pattern):创建指定日期模板的格式化日期。
日期模板:
yyyyMMdd HH:mm:ss E 2023/03/09 14:05:16 周四
常用方法:
format(Date date) | String | 将Date对象按日期模板转换为字符串 |
parse(String str) | Date | 将满足日期模板的字符串反转为Date对象 |
Calendar类
表示日历的类,包含了很多日历相关的信息
是一个抽象类,无法创建对象,可以通过静态方法getlnstrance()获取Calendar类的实例
Calendar c=Calendar.getInstance();
日历字段:在Calendar类中,定义了很多被final static修饰的静态常量,称为日历字段。实际是一个数字,用于获取指定日历信息。
get(int filed) | 根据日历字段获取对应的值 |
getMaximum(int filed) | 获取指定日历字段的最大值,如日期最大为31 |
getActualMaximum(int filed) | 获取知道你日历字段的实际最大值,如11月的日期最大为30 |
getTime() | 将Calendar对象转换为Date对象 |
set(int filed,int value) | 将指定的日历字段设置为指定值 |
set(int year,int month,int date) | 同时设置日历的年月日 |
setTime(Date date) | 将Date对象作为参数设置日历的信息 |
使用Calendar类实现万年历:
import java.util.Calendar;
import java.util.Scanner;
public class Wannianli {
public static void main(String[] args) {
Calendar c=Calendar.getInstance();
Scanner sc=new Scanner(System.in);
System.out.println("输出年份");
int year=sc.nextInt();
System.out.println("输出月份");
int month=sc.nextInt();
c.set(year,month-1,1);
int maxDate=c.getActualMaximum(Calendar.DATE);
int count=0;
System.out.println("一\t二\t三\t四\t五\t六\t日");
int week=c.get(Calendar.DAY_OF_WEEK);
if(week==1){
System.out.print("\t\t\t\t\t\t");
count+=6;
}else {
for(int j=1;j<=week-2;j++){
System.out.print("\t");
count++;
}
}
for(int i=1;i<=maxDate;i++){
System.out.print(i+"\t");
count++;
if (count%7==0){
System.out.println();
}
}
}
}
方法调用时传值问题
总结
参数为引用类型,且在方法中直接操作该参数时,才会对实际参数造成影响。
包装类:
Java是纯面向对象语言,宗旨是将一切事物视为对象处理。
但原始类型不属于对象,不满足面向对象的思想。但原始类型无需创建对象,保存在栈中,效率更高。
包装类:为了既保证效率又让原始类型也有对应的类类型。
包装类就是原始类型对应的类类型:
包装类常用于字符串与原始类中之间的转换。
在web应用中,从浏览器页面中获取数据提交到服务器,全部都是String类型,所以一定要使用字符串转换为原始类型的方法。
包装类 | 原始类型 |
Byte | byte |
Short | short |
Integer | int |
Long | long |
Float | float |
Double | double |
Character | char |
Boolean | boolean |
特点:
八个原始类型中,除了int char其余包装类都是将原始类型的首字母改为大写。int Integer char对应Character
包装类都是被final修饰的,不能被继承
除了Character类,其余包装类都有两个过时的构造方法,参数对应的原始类型或字符串。Character只有一个参数为char类型的构造方法
构造方法的目的都是将原始类的数据转换为包装类的对象。
除了Character类,其余包装类都有静态方法"parse原始类型单词(String str)",用于将字符串转换为相应的原始类型。
数值型的包装类parseXXX方法:如果参数不是对应的数字就会抛出NumberFormat异常,如"123a"或"123.4"都会报错
boolean的包装类Boolean的parseBoolean()方法,如果参数不是true这个单词的四个字母,转换结果就是false。
除了Boolean类,其余包装类都有MAX_VALUE和MIN_VALUE这两个静态属性。用于获取对应类型支持的最大最小值。
所有包装类都重写了toString(),用于将包装类对象转换为String对象。
字符串与原始类型之间的转换
字符串转换为原始类型
使用原始类型对应的包装类,调用parseXXX(String str)方法
原始类型转换为字符串:
使用String类的String.valueOf(Object obj)
拼接空白字符串
将原始类型转换为包装类后,调用toString()
装箱和拆箱
自动装箱缓冲区:
使用自动装箱给包装类对象赋值:值的范围在[-128 127]之间时,共享数据,==判断结果为true。当不在这个范围内之时,就会创建新的包装类对象,会有不同的地址,判断结果为false
引用类型对象比较相同时,不要使用==,包括包装类对象,比较相同时,使用包装类重写的equals方法
异常:
程序没有按照开发者的意愿正常执行,中途出现错误,导致程序中断。
异常的产生:异常在程序中以对象的形式存在,当代码执行过程中出现异常,虚拟机会自动创建一个对象,如果没有对该异常对象进行处理,就会导致程序中断,不再执行后续内容。
异常的分类:异常在程序中以对象的形式存在,就有相应的类:
Error:如果出现xxxError,如StackOverFlowError,栈溢出,无法通过额外的代码解决,只能通过修改源代码。
Exception异常:
RunTimeException运行时异常:
如果一个异常类属于RunTimeException异常类的子类,称这个异常为运行时异常,可以通过编译,运行时可以抛出异常对象。
常见运行时异常 | 说明 | 出现的情况 |
NullPointerException | 空指针异常 | 如用空指针null调用属性或方法 |
IndexOutOfBoundsException | 索引越界异常 | 当使用某个对象的索引超出索引范围 |
NumberFormatException | 数字格式异常 | 如调用包装类的parseXX()方法,如果参数不能转换 |
InputMismatchException | 输入不匹配异常 | 如使用Scanner接收控制台输入时,如果输入的数据不是对应的类型 |
ClassCastException | 对象转型异常 | Person p=(Person)Dog dog; |
ArithmeticException | 算数异常 | 分母为零 |
编译时异常:
如果一个异常类不属于RunTimeException异常类的子类,称为编译时异常,无法通过编译,必须要处理异常后才能正常编译运行
常见编译时异常 | 说明 | 出现的情况 |
IOException | 输入输出流异常 | 使用流对象 |
FileNotFoundException | 文件未找到 | 以方法的参数作为文件对象 |
SQLException | 数据库相关异常 | 操作数据库时 |
处理异常:处理Exception类的子类异常,目的是为了保证程序正常执行。
方式一:try-catch-fianlly语句
这种方式,无论会不会抛出异常,都能让程序正常执行。
执行流程:先执行try中的内容,当出现异常,与后续catch中的每个异常进行匹配,如果匹配到对应的类型或异常父类时,执行后续大括号中的内容,最终执行finally中的内容。
try-catch-finally使用时注意:
如果代码抛出多个异常,可以使用多个catch进行捕获,需要将子类异常放前面,父类异常放后面。
try catch finally都不能单独使用,try必须配合chatch或finally使用
无论try中的代码是否抛出异常,finally中的代码一定执行
执行try中的代码时,如果出现异常,try中其余的代码就不再执行
try中定义的内容,无法在try之外的地方使用。
try中如果有return,不影响finally的执行。finally优先于return执行。
方式二:throws关键字
可以让编译时异常通过编译;在定义方法时,通过该关键字声明方法可能跑出的异常。
用法:方法的参数部分后,添加throws异常类型1,异常类型2.
throw和throws
throws表示用于声明方法有可能出现的异常,使用时写在方法的小括号后。
throw用于手动抛出异常对象。使用时写在方法体中,"throw"异常对象。常用于满足某种条件时,强制中断程序。
自定义异常:
如果需要在某种情况下中断程序,可以自定义一个异常类,在通过throw关键字手动抛出自定义异常
自定义异常步骤:
1.创建一个类,继承某个异常类:
如果继承的是RuntimeException,表示自定义的异常类属于运行时异常。该异常对象可以不用处理。
如果继承的是非RuntimeException,表示自定义的异常类属于编译时异常,该异常对象必须处理,
2.可选操作,定义代餐构造方法,参数为String类型的异常信息,调用父类中的构造方法。