目录
7 String、StringBuffer和StringBuilder的比较
1 注解和四种元注解(作用不大,看源码用)
1):@Override注解,重写父类方法,该注解只能用于方法,没有重写时写了会报错,重写时不写不会报错
2):@interface,修饰类,表示注解类
3):@Deprecated:表示某个元素(类、字段、方法、包、参数)过时了,不推荐使用,但是依然可以用(修饰之后元素名会有一个横线),新旧版本的兼容过度
4):@SuppressWarnings({”希望抑制警告的信息1“,”all“}):印制警告信息,作用范围与自己写的位置有关,放在方法外面,作用范围只是方法,作用范围最大就是类,放在类外面
元注解:修饰注解的注解
5):@Retention(RetentionPolicy):指定注解的保留时间,三种:SOURCE(编译器使用后,丢弃这种策略)\CLASS(记录在class文件中,运行时不保留注解,这是默认值)\RUNTIME(记录在class文件中,JVM保留注解,通过反射获取该注释)
6):@Target(value={CONSTRUCTOR,FIELD}):指定它修改的Annotation(注解类)能用于修饰哪些程序元素
7):@Documented:用于指定被修饰的注解类生成javadoc文档的时候可以看到该注解,定义为Documented的注解都必须设置为RUNTIME
8):@Inherited:A类使用了被它修饰的注解,A类的子类自动具有该注解
2 异常
2.1 异常介绍
Throwable( extends Object implements Serializable)->Error\Exception
1):Error(错误):Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。StsckOverflowError[栈溢出]和OOM[out of memory],Error是严重错误,程序会崩溃。
2):Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指针访问,试图读取不存在的文件,分为两大类:运行时异常[程序运行时发生的异常,非受检异常,数组越界,算数异常]和编译时异常[编程时,编译器检查出的异常,受检异常]。
2.2 编译时异常和常见的运行时异常
1):编译异常:是指在编译期间,就必须处理的异常,否则代码不能通过编译:SQLException、FileNotFileException...
2):常见的运行时异常:
a.NullPointException空指针异常
b.ArithmeticException数学运算异常
c.ArrayIndexOutOfBoundsException数组下标越界异常
d.ClassCastException 类型转换异常
e.NumberFormatException 数字格式不正确异常
2.3 异常处理
运行异常默认处理:如果程序员没有显示的处理运行时异常,默认throws,编译异常必须处理
1).try-catch-finally:程序员在代码中捕获发生的异常,自行处理
try{
代码/可能有异常
}catch(Exception e){
//捕获到异常
//1.当异常发生时
//2.系统将异常封装成Exception 对象e,传递给catch()
//3.得到异常对象后程序员自己处理
//4.没有发生异常,catch块不执行
}catch{
//
}finall{
//不管try代码块是否有异常发生,始终要执行finally}
2):如果发生异常,异常后面的代码不会执行,直接执行catch,正常执行后面的代码
3):如果try代码块可能有多个异常,可以使用多个catch分别捕获不同的异常,子类异常写在前面,父类异常写在后面
4):try-finnaly:没有进行捕获异常,因此程序直接崩掉,就是执行一段代码,不管是否发生异常,都必须执行的某个业务逻辑
try{
//代码...
}finally{//总是执行
}
5):throws XXXException,XXXException:将发生的异常抛出,可以是多个异常,交给调用者(方法)来处理(t-c-f),可以一直throws到main交给JVM处理,最顶级的调用者是JVM(1.输出异常信息2.退出信息)
6):子类重写父类方法时,对抛出的异常规定:子类重写的方法所抛出的异常要么和父类抛出的异常一致,要么为父类抛出的异常类型的子类型
class Father{
public void print() throws RuntimeException{
}
}
class Son extends Father{
@Override
public void print() throws NullPointerException{
}
}
2.4 自定义异常
1):概念:当程序出现了某些错误,但该错误信息并没有在Throwable子类中描述处理子类,这个时候可以自己来设计异常类,用于描述该错误信息
2):自定义异常类的步骤
a:定义类:自定义异常类名(自定义)继承Exception或RuntimeException
b:如果继承Exception,属于编译异常
c:如果继承RuntimeException,属于运行时异常
public class CustomeException {
public static void main(String[] args) {
int age=1020;
if(!(age>=0&&age<=120)){
throw new AgeException("年龄范围需要在0-120之间");
}
System.out.println();
System.out.println("您的年龄范围正确");
}
}
class AgeException extends RuntimeException{
public AgeException(String message) {
super(message);
}
}
2.5 throw VS throws
throws:异常处理的一种方式,位置:方法声明处,后面跟的东西:异常类型
throw:手动生成异常对象的关键字,位置:方法体中,后面跟的东西:异常对象
public class Exercise02 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
if(args.length!=2){
throw new ArrayIndexOutOfBoundsException("数字个数不对");
}
int n1= Integer.parseInt(args[0]);
int n2= Integer.parseInt(args[1]);
cal(n1,n2);
} catch (ArithmeticException e) {//计算错误
e.printStackTrace();
}catch (NumberFormatException e){//数据格式不正确
e.printStackTrace();
}catch (ArrayIndexOutOfBoundsException e){//缺少命令行参数异常
e.printStackTrace();
}
}
public static void cal(int n1,int n2){
System.out.println("计算结果是"+n1/n2);
}
}
3 包装类
3.1包装类概述
1):八种基本数据类型相应的应用类型-包装类
2):有了类的特点,就可以调用类中的方法
3.2拆箱和装箱
装箱:基本类型->包装类型拆箱反之
1):jdk5之前手动装箱拆箱,以后自动装箱和拆箱
2):自动装箱底层调用的是valueOf和intValue方法,比如Integer.valueOf()
//jdk5之前手动装箱拆箱(以int为例举例)
//int i=3;
//Integer i1=new Integer(i1);方法1
//Integer i2=Integer.valueOf(i);方法2
//拆箱:int n=Integer.intValue();
//自动装箱:Integer integer01=i;
//自动拆箱:int n3=integer01;
3.3 包装类型和String类型相互转换
1):以Integer和String转换为例
//包装类型->String类型
String s1=integer01.toString();
String s2=String.valueOf(integer01);
String s3=integer01+"";
System.out.println(s3);
//String->包装类
Integer integer02=new Integer(s1);
Integer integer03=Integer.valueOf(s2);
3.4 Integer和Character类的常用方法
System.out.println(Integer.MAX_VALUE);//返回最小值
System.out.println(Integer.MIN_VALUE);//返回最大值
System.out.println(Character.isDigit('a'));//判断是不是数字
System.out.println(Character.isLetter('a'));//判断是不是字母
System.out.println(Character.isUpperCase('a'));//判断是不是大写
System.out.println(Character.isLowerCase('a'));//判断是不是小写
System.out.println(Character.isWhitespace('a'));//判断是不是空格
System.out.println(Character.toUpperCase('a'));//转成大写
System.out.println(Character.toLowerCase('A'));//转成小写
3.5 Integer练习题
4 String类
4.1 String类结构刨析
1):String对象用于保存字符串,也就是一组字符序列,String类的private final char value[]来存放字符串内容,不可以修改(单个字符内容可以修改,不可以指向新的对象,地址不可以修改)
2):字符串常量对象是用双引号括起的字符序列。eg:"你好"、"12.8"、"adahcv"
3):字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节
4):String类较常用构造方法(其它看手册):
char[] a={'s','b'};
String s0="哈喽";//指向常量池的地址空间
String s1=new String();
String s2=new String("嗨嗨嗨"/*String original*/);//在堆中创建空间
String s3=new String(a/*char[] a*/);
String s4=new String(a,0,1/*char[] a,int startIndex,int count*/);
4.2 String对象的特性
4.3 String常用方法
1):intern()方法返回与对象相同内容的常量池的地址,否则将对象内容添加到常量池中再返回
String a="ha";//指向常量池中
String b=new String("ha");//指向堆中的对象
System.out.println(a==b);
System.out.println(a==b.intern());//intern()方法返回与b相同的常量池的地址
//否则将b添加到池中
System.out.println(b==b.intern());
2):equals(),区分大小写,判断内容是否相等
3):equalslgnoreCase(),忽略大小写的判断内容是否相等
4):length(),获取字符的个数,字符串的长度
5):indexOf(),获取字符在字符串中第一次出现的下标,索引下标从0开始,找不到返回-1
6):lastIndexOf(),获取字符在字符串中最后一次出现的索引,索引从0开始,找不到返回-1
7):substring(),截取从指定位置x开始到后面所有的字符串或从位置x截取到位置为y-1的子串
8):trim(),去前后空格
9):charAt(),获取某索引处的字符
10):toUpperCase(),转换为大写
11):toLowerCase(),转换为小写
12):concat(),拼接字符串,可以多次使用str.concat(" d").concat("dja");
13):compareTo(),比较两个字符串的大小,前者大返回正数,反之返回负数,长度不相等返回长度的差值,长度相等返回字符的差值,eg.jchn-java返回的是c-a的值2
14):toCharArray(),转换成字符数组
15):format(),格式字符串,%s字符串,%c字符,%d整型,%.2f浮点型小数只保留两位,占位符由后面的变量来替换,顺序替换
16):replace("x","y"),将字符串的x替换成y
17):split(),分割字符串,对于某些分割字符,我们需要转义符\,比如用\\分割应该写\\\\
4.4 String 练习题
public class Homework01 {
public static void main(String[] args) {
//将字符串的指定部分进行反转,eg.abcdef->aedcbf
try {
System.out.println(revers("abcdef",2,5));
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static String revers(String str,int start,int end){
if(!(str !=null&&start<end&&start>0&&end<str.length())){
throw new RuntimeException("参数不正确");
}
char[] cr=str.toCharArray();
char temp;
for(int i=start-1 ,j=end-1;i<j;i++,j--){
temp=cr[i];
cr[i]=cr[j];
cr[i]=temp;
}
return new String(cr);
}
}
public class Homework02 {
/*输入用户名、密码、邮箱,正确提示注册成功,否则抛出异常
*/
public static void main(String[] args) {
try {
judge("mike","456557","55555");
System.out.println("恭喜你,注册成功");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void judge(String name, String pass, String email) {
int nlength = name.length();
int plength = pass.length();
char[] echar = email.toCharArray();
if (!(2 <= nlength && nlength <= 4)) {
throw new RuntimeException("用户名长度为2-4");
}
if (!(plength==6&&isDigital(pass))){
throw new RuntimeException("密码长度为6,要全是数字");
}
int index01=email.indexOf("@");
int index02=email.indexOf(".");
if(!(index01<index02&&index01!=-1)){
throw new RuntimeException("邮箱包含@和.,@在.前面");
}
}
public static boolean isDigital(String pass){
char[] pchar = pass.toCharArray();
for(int i=0;i<pass.length();i++){
if(!('0'<=pchar[i]&&pchar[i]<='9')){
return false;
}
}
return true;
}
}
5 StringBuffer类
5.1 StringBuffer类结构剖析
1):java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删
2):很多方法和String相同,但是StringBuffer是可变长度的
3):StringBuffer是一个容器
4):StringBuffer的直接父类是 AbstractStringBuilder;StringBuffer实现了Serializable,即StringBuffer的对象可以串行化;在父类中 AbstractStringBuilder有属性 char[] value ,不是final类型,内容存在堆中
5.2 String类 VS StringBuffer类
1):String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低//private final char valuel;
2):StringBuffer保存的是字符串变量,里面的值可以更改;StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高;//char[] value;//这个放在堆.
5.3 StringBuffer的转换
//使用构造器
1):StringBuffer(),构造一个其中不带字符的字符串缓冲区,其初始容量为16个字符
2):StringBuffer(CharSequence seq),public java.lang.StringBuilder(CharSequence seq)构造一个字符串缓冲区,它包含与指定的CharSequence相同的字符
3):StringBuffer(int capacity) //capacity[容量],构造一个不带字符,但具有指定初始容量的字符串缓冲区。即对char[]大小进行指定
4):StringBuffer(String str),构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容,长度为字符串的长度+16
//使用append()转换
String str=new String("你好啊");
StringBuffer stringBuffer = new StringBuffer();
stringBuffer=stringBuffer.append(str);
//StringBuffer->String
//1.使用toString()方法
str=stringBuffer.toString();
//2.使用构造器来搞定
String s01=new String(stringBuffer);
5.4 StringBuffer的常用方法
1):增append,新内容添加在字符串后面
2):删delete(start,end),将索引下标为>=start <end间的内容删除,不含end,含start
3):改replace(start,end,string),将s索引下标为>=start <end间的内容替换掉,不含end,含start
4):查indexOf(),查找子串在字符串第一次出现的索引,找不到返回-1
5):插insert(int,str),在索引为int的位置插入str,索引int后面的内容后移
6):获取长度length()
练习:对输入的价格进行处理,进行.前每三位加,处理
public void print(){
StringBuffer stringBuffer = new StringBuffer(prince);
System.out.print(name+"\t");
int index=stringBuffer.indexOf(".");
for(int i=index-3;i>0;i=i-3){
stringBuffer.insert(i,",");
}
System.out.print(stringBuffer);
}
}
6 StringBuilder类
6.1 StringBuilder类结构剖析
1):一个可变的字符序列。此类提供一个与StringBuffer 兼容的API,但不保证同步(StringBuilder 不是线程安全)。该类被设计用作 StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer要快。
2):在StringBuilder上的主要操作是append和insert方法,可重载这些方法,以接受任意类型的数据。
3):方法和使用StringBuffer一样,StringBuilder没有做互斥处理,单线程才可以使用
7 String、StringBuffer和StringBuilder的比较
1):StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且方法也包样2
2):String :不可变字符序列,效率低,但是复用率高。
3): StringBuffer :可变字符序列、效率较高(增删)、线程安全
4):StringBuilder :可变字符序列、效率最高、线程不安全
5): String 使用注意说明:
string s =“ a ”;//创建了一个字符
S +=" b ”◇//实际上原来的" a "字符串对象已经丢弃了◇现在又产生了一个字符
串 s +” b "(也就是" ab ")。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大
影响程序的性能
结论:如果我们对 String 做大量修改,不要使用 String