目录
一、注解
(1)也被称为元数据,用于修饰包,类,方法,变量,构造器等
(2)与注释一样,不影响程序,但注解可以被编译或运行
1、@Override
(1)该注解只能修饰方法,在方法上方,限定某个方法是重写方法,如果写了@Override,编译器就会检查该方法是否真的重写了父类的方法,没有重写就会报错
(2)如果不写@Override,方法重写了父类的方法,仍然构成重写
class Father{
public void run(){
}
}
class Son extends Father{
@Override
public void run() {
}
}
2、@Deprecated
用于表示某个元素已过时,不建议使用,但不代表不能用
public class Test {
public static void main(String[] args) {
A a = new A();
}
}
@Deprecated
class A{
}
3、@SuppressWarnings
抑制编译器警告,可以在(" ")中写入希望抑制的警告信息
根据希望抑制的警告位置不同,信息不同,抑制范围也不同
public class Test {
@SuppressWarnings("all")
public static void main(String[] args) {
}
}
4、元注解
修饰注解的注解
(1)@Retntion:指定注解的作用范围
(2)@Target:指定注解可以在哪些地方使用
(3)@Documented:指定注解是否会在javadoc体现
(4)@Inherited:子类会继承父类注解
二、异常
1、异常分类
程序执行中发生的不正常的情况(语法和逻辑错误不属于异常),分为两大类
(1)Error:JVM无法解决的严重问题
(2)Exception:因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理,分为运行异常和编译异常
2、运行异常
不必须处理的异常
(1)空指针异常
String name = null;
System.out.println(name.length()); //NullPointerException
(2)数学运算异常
int n1 = 1;
int n2 = 0;
int n = n1 / n2; //ArithmeticException
(3)数组下标越界异常
int[] arr = {1,2,3};
System.out.println(arr[3]); //ArrayIndexOutOfBoundsException
(4)类型转换异常
Father f = new Son1(); //向上转型
Son1 s1 = (Son1) f; //向下转型
Son2 s2 = (Son2) f; //ClassCastException
(5)数字格式不正确异常
String name1 = "123";
String name2 = "你好";
int n1 = Integer.parseInt(name1); //将String转成int
int n2 = Integer.parseInt(name2); //NumberFormatException
3、编译异常
在编译期间就必须处理的异常,否则代码不能通过编译
(1)参数异常
(2)加载一个不存在的类时发生的异常
(3)操作文件时发生的异常
(4)操作数据库时发生的异常
4、异常处理机制
异常处理后,程序可以继续执行
(1)try/catch/finally:在try代码块中捕获发生的异常,将异常封装成Exception对象e,传递给catch,自行处理(catch和finally根据具体情况可以不写)
执行顺序:如果异常发生了,则try代码块中异常发生代码后面的代码不会执行,直接进入到catch,如果异常没有发生,则顺序执行try的代码块,不会进入到catch
不管try代码块是否有异常发生,finally都会执行,finally执行完之后,才会返回执行try或者catch中的return或者throw语句,如果finally中有return或者throw语句则不会返回执行,直接终止
public static void main(String[] args) {
try {
String name = null;
int n = name.length();
System.out.println(n);
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
System.out.println("finally执行");
}
System.out.println("程序继续");
}
输出:
Cannot invoke "String.length()" because "name" is null
finally执行
程序继续
可以有多个catch语句捕获不同的异常,要求子类异常在前,父类异常在后,如果发生异常,只会匹配一个catch
public static void main(String[] args) {
try {
String name = null;
System.out.println(name.length());
int n1 = 1;
int n2 = 0;
int n = n1 / n2;
} catch (NullPointerException e) {
System.out.println(e.getMessage());
} catch (ArithmeticException e) {
System.out.println(e.getMessage());
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
}
}
(2)throws:抛出异常,交给上级方法的调用者来处理,最顶级的处理者就是JVM
在方法声明中用throws语句可以声明抛出异常的列表
throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类
public static void main(String[] args) throws Exception {
}
public class Test {
public static void main(String[] args) throws NullPointerException,ArithmeticException{
}
}
(3)对于运行异常,如果程序没有显示的处理异常,默认throws方式处理
(4)子类重写父类方法时,子类重写的方法,所抛出的异常类型要么和父类方法抛出的异常一致,要么为父类方法抛出的异常类型的子类型
class Father{
public void run() throws Exception{
}
}
class Son extends Father {
@Override
public void run() throws NullPointerException{
}
}
(5)在throws处理异常的过程中,如果有try/catch/finally,就相当于处理异常,就不必throws处理
5、自定义异常
定义类:自定义异常类名,继承Exception(编译异常)或RuntimeException(运行异常)
public class Test {
public static void main(String[] args) {
int n = -1;
//要求n是正数
if(n<=0)
throw new Numbers("n不是正数");
}
}
class Numbers extends RuntimeException {
public Numbers(String message) {
super(message);
}
}
throws:异常处理的一种方式,方法声明处使用,接异常类型
throw:手动生成异常对象的关键字,方法中使用,接异常对象
String name = "asd";
String password = "156461";
String mail = "asd@.com";
try {
a();
System.out.println("成功");
} catch (Exception e) {
System.out.println(e.getMessage());
throw new RuntimeException(e);
} finally {
}
}
public static boolean a (){
if(true)
throw new RuntimeException("asdasd");
return true;
三、常用类
1、包装类
八种基本类型相对应的引用类型,其中1-6继承了number类,1-8都是Object的子类
(1)byte----Byte (2)short----Short (3)int----Integer (4)long----Long
(5)float----Float(6)double----Double(7)char----Character(8)boolean----Boolean
(1)包装类和基本类型的相互转换,装箱:基本类型-->包装类型 拆箱:包装类型-->基本类型
手动装箱/拆箱:
int n = 1;
Integer i1 = new Integer(n);
Integer i2 = Integer.valueOf(n);
int m1 = i1.intValue();
int m2 = i2.intValue();
自动装箱/拆箱:
int n = 1;
Integer i = n; //底层调用的仍是Integer.valueOf(n);
int m = i; //底层调用的仍是i.intValue();;
(2)包装类和字符串的相互转换
Integer n = 1;
String str = "123";
String str1 = n+"";
String str2 = n.toString();
String str3 = String.valueOf(n);
Integer n1 = Integer.parseInt(str);
Integer n2 = new Integer(str);
(3)包装类的常用方法
System.out.println(Integer.MIN_VALUE);
System.out.println(Integer.MAX_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'));
2、 StringBuffer类
(1)StringBuffer为final类,是一个容器,可变长度的
(2)直接父类是AbstactStringBuilder,实现了Serializable,即StringBuffer对象是可串行化的(对象可以网络传输,可以保存到文件)
(3)父类AbstactStringBuilder中有成员char[ ] value,在堆中存放字符串
(4)String保存的是字符串常量,值不可以更改,更改的是地址
StringBuffer保存的是字符串变量,值可以更改,不用每次更改地址(不用每次创建新对象)
(5)StringBuffer()构造器
构造一个其中不带字符的字符串缓冲区,初始容量为16个字符
StringBuffer sb = new StringBuffer();
(6)StringBuffer(int capacity)构造器
构造一个不带字符,但具有指定初始容量的字符串缓冲区
StringBuffer sb = new StringBuffer(20);
(7)StringBuffer(String str)构造器
构造一个字符串缓存区,并将其内容初始化为指定的字符串内容,容量为str.length+16个字符
StringBuffer sb = new StringBuffer("字符串");
(8)StringBuffer(CharSequence seq)构造器
构造一个字符串缓冲区,包含与指定的CharSequence相同的字符
(9)String和StringBuffer的转换
String s = "字符串";
StringBuffer sb = new StringBuffer("字符串");
StringBuffer sb1 = new StringBuffer(s);
StringBuffer sb2 = new StringBuffer();
StringBuffer sb3 = sb2.append(s); //使用append方法
String s1 = new String(sb);
String s2 = sb.toString(); //使用toString方法
(10)增加字符串: 变量名.append();
StringBuffer sb = new StringBuffer("字符串");
sb.append(1).append("2");
(11) 删除子串: 变量名.delete(a,b); 范围:从a开始,到b结束,不包括b
StringBuffer sb = new StringBuffer("01234567");
sb.delete(4,6);
(12)替换子串:变量名.replace(a,b,替换后的子串); 把从位置a开始,到b结束的子串替换
StringBuffer sb = new StringBuffer("01234567");
sb.replace(4,6,"54");
(13)插入字符串: 变量名.insert(a,插入的字符串); 在位置a前插入字符串
StringBuffer sb = new StringBuffer("01234567");
sb.insert(3,"999");
3、StringBulider类
(1)StringBuilder为final类
(2)直接父类是AbstactStringBuilder,实现了Serializable,即StringBuilder对象是可串行化的(对象可以网络传输,可以保存到文件)
(3)父类AbstactStringBuilder中有成员char[ ] value,在堆中存放字符串
(4)StringBuilder方法没有做互斥处理,即没有synchronized关键字,因此在单线程情况使用
(5)String,StringBuffer,StrinBuilder比较:
String代表不可变的字符序列,效率低,复用率高(不适应于对字符串大量修改)
StringBuffer代表可变的字符序列,效率高,线程安全
StrinBuilder代表可变的字符序列,效率最高,线程不安全
4、Math类
System.out.println(Math.abs(-9)); //abs,求绝对值
System.out.println(Math.pow(2,3)); //pow,求2的3次方
System.out.println(Math.ceil(-1.1)); //ceil,向上取整
System.out.println(Math.floor(-1.1)); //floor,向下取整
System.out.println(Math.round(-1.5)); //round,四舍五入
System.out.println(Math.sqrt(9)); //sqrt,开方
System.out.println(Math.max(1,2)); //max,获取两个数的最大值
System.out.println(Math.min(1,2)); //min,获取两个数的最小值
System.out.println(Math.random()); //random,随机返回[0,1)之间的小数
int n = (int)(a+Math.random()*(b-a+1)); //random,随机返回[a,b]之间的整数
5、Arrays类
int[] arr = {1,3,5,2,4,6};
//toString,将数组拼接为字符串
System.out.println(Arrays.toString(arr));
//sort,排序
Arrays.sort(arr);
//binarySearch,二分查找,要求数组有序,返回下标,不存在返回-(low+1)
int index = Arrays.binarySearch(arr,1);
//copeOf,复制要求数量的数组元素到新数组中
int[] ara = Arrays.copyOf(arr,3);
//fill,填充要求元素到整个数组中
Arrays.fill(arr,7);
//equals,比较两个数组元素是否完全一致
System.out.println(Arrays.equals(arr,ara));
//asList,将一组值转换成List
List<Integer> list = Arrays.asList(1,2,3,4,5);
6、System类
int[] arr = {1,2,3,4};
int[] ara = {4,3,2,1};
//arraycopy,拷贝要求数量的数组元素到新数组中替换
System.arraycopy(arr,0,ara,0,4);
//currentTimeMillens,返回当前时间距离1970-1-1的毫秒数
System.out.println(System.currentTimeMillis());
//gc,运行垃圾回收机制
System.gc();
//exit,退出当前程序,0代表正常状态退出
System.exit(0);
7、BigInteger类和BigDecimal类
BigInteger:保存比较大的整形
BigInteger b1 = new BigInteger("999999999999");
BigInteger b2 = new BigInteger("999999999999");
//对BigInteger进行加减乘除,需要对应的方法,不能直接进行+-*/
System.out.println(b1.add(b2)); //add
System.out.println(b1.subtract(b2)); //subtract
System.out.println(b1.multiply(b2)); //multiply
System.out.println(b1.divide(b2)); //divide
BigDecimal:保存精度更高的浮点型
BigDecimal b1 = new BigDecimal("99.999999999999999999");
BigDecimal b2 = new BigDecimal("1.1");
BigDecimal b3 = new BigDecimal("7");
//对BigDecimal进行加减乘除,需要对应的方法,不能直接进行+-*/
System.out.println(b1.add(b2)); //add
System.out.println(b1.subtract(b2)); //subtract
System.out.println(b1.multiply(b2)); //multiply
System.out.println(b1.divide(b2)); //divide
//在调用divide方法时,可能抛出异常,除不尽,需要指定精度,保留到分子精度
System.out.println(b1.divide(b3,BigDecimal.ROUND_CEILING));
8、Date类
//获取当前系统时间,默认输出的日期格式是国外的方式
Date d1 = new Date();
System.out.println(d1);
//获取从1970开始,经过指定毫秒数得到的时间
Date d2 = new Date(999999999999L);
System.out.println(d2);
//获取从1970开始,到指定的时间,经过的毫秒数
System.out.println(d1.getTime());
System.out.println(d2.getTime());
//创建SimpleDateFormat对象,可以指定相应的格式
SimpleDateFormat s1 = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
System.out.println(s1.format(d1));
//可以把一个格式化字符串转换为一个对应的Date
String s2 = "1998年09月10日 08:24:10 星期一";
Date d3 = s1.parse(s2); //此处有异常,抛出ParseException
System.out.println(s1.format(d3));
9、Calendar类
是一个抽象类,构造器是私有的,通过getInstance()来获取实例
Calendar c = Calendar.getInstance();
System.out.println(c);
System.out.println(c.get(Calendar.YEAR));
//月要+1,Calendar返回月的时候,按照0开始编号
System.out.println((c.get(Calendar.MONTH))+1);
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.HOUR));
//24小时制
System.out.println(c.get(Calendar.HOUR_OF_DAY));
System.out.println(c.get(Calendar.MINUTE));
System.out.println(c.get(Calendar.SECOND));
10、LocalDate类
LocalDate ld = LocalDate.now();
System.out.println(ld);
System.out.println(ld.getYear());
System.out.println(ld.getMonthValue());
System.out.println(ld.getMonth());
System.out.println(ld.getDayOfMonth());
LocalTime lt = LocalTime.now();
System.out.println(lt);
System.out.println(lt.getHour());
System.out.println(lt.getMinute());
System.out.println(lt.getSecond());
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
System.out.println(ldt.getYear());
System.out.println(ldt.getMonthValue());
System.out.println(ldt.getMonth());
System.out.println(ldt.getDayOfMonth());
System.out.println(ldt.getHour());
System.out.println(ldt.getMinute());
System.out.println(ldt.getSecond());
//按格式输出
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH小时mm分钟ss秒");
String format = dtf.format(ldt);
System.out.println(format);
//通过静态方法now(),获取表示当前时间戳的对象
Instant i1 = Instant.now();
System.out.println(i1);
//通过from可以把Instant转成Date
Date d = Date.from(i1);
//通过Date的toInstant()可以把date转成Instant对象
Instant i2 = d.toInstant();
四、正则表达式(Regular Expression)
String content = "abc123";
String regStr = "123"; //123
//创建一个模式对象:调用Pattern的静态方法compile(pattern)
Pattern pattern = Pattern.compile(regStr);
//创建一个匹配器对象:调用Pattern的静态方法matcher(content)
Matcher matcher = pattern.matcher(content);
//matcher.find():根据指定的规则,定位满足规则的子串,返回布尔值
while (matcher.find()){
//开始循环匹配,放到group中
System.out.println(matcher.group(0));
}
//默认区分大小写
String regStr = "abc"; //abc都区分大小写
//不区分大小写的方法
String regStr1 = "(?i)abc"; //abc都不区分大小写
String regStr2 = "a(?i)bc"; //bc不区分大小写
String regStr3 = "a((?i)b)c"; //b不区分大小写
Pattern pattern = Pattern.compile(regStr,Pattern.CASE_INSENSITIVE);
(1)转义符:
String content = ".*+()$/?^{}[]\\";
//\\:需要用转义字符的:. * + ( ) $ / ? ^ { } [ ] \
String regStr = "\\.\\*\\+\\(\\)\\$\\/\\?\\^\\{\\}\\[\\]\\\\";
//在[]里可以不用转义字符,就为字符本身,除了[]
String regStr = "[.*+()$/?^{}\\\\]";
(2)字符匹配符:
String content = "abcde12*";
//[]:可接收的字符列表
String regStr1 = "[abc]"; //a,b,c
//[^]:不接收的字符列表
String regStr2 = "[^abc]"; //d,e,1,2,*
//-:连字符
String regStr3 = "[a-z]"; //a,b,c,d,e
//.:匹配单个除\n以外的任何字符
String regStr4 = "a..d"; //abcd
//\\d:匹配单个数字字符
String regStr5 = "\\d"; //1,2
//\\D:匹配单个非数字字符
String regStr6 = "\\D"; //a,b,c,d,e,*
//\\w:匹配单个数字、字母、下划线
String regStr7 = "\\w"; //a,b,c,d,e,1,2
//\\W:匹配单个非数字、字母、下划线
String regStr8 = "\\W"; //*
//\\s:匹配单个空白字符(空格、制表符)
String regStr9 = "\\s"; //
//\\S:匹配单个非空白字符(空格、制表符)
String regStr10 = "\\S"; //a,b,c,d,e,1,2,*
(3)限定符:用于指定其前面的字符和组合项连续出现多少次(贪婪匹配)
String content = "abc111abcabc";
//*:指定字符重复0次或n次
String regStr1 = "(abc)*"; //abc,abcabc
//+:指定字符重复1次或n次
String regStr2 = "1+(abc)*"; //111abcabc
//?:指定字符重复0次或1次
String regStr3 = "1+abc?"; //111abc
//{n}:指定n个匹配
String regStr4 = "[abc]{3}"; //abc,abc,abc
//{n,}:指定至少n个匹配
String regStr5 = "[abc]{3,}"; //abc,abcabc
//{n,m}:指定至少n个但不多于m个匹配
String regStr6 = "[abc]{3,5}"; //abc,abcab
//?:非贪婪匹配
String regStr7 = "\\d+?"; //1,1,1
(4)选择匹配符:
String content = "ab123cd123ef";
//|:匹配 | 之前或之后的字符
String regStr = "ab|cd|ef"; //ab,cd,ef
(5)定位符
String content = "123abc";
//^:指定起始字符(以整个字符串开始,不包括子串)
String regStr1 = "^[0-9]+[a-z]*"; //123abc
//$:指定结束字符(以整个字符串结束,不包括子串)
String regStr2 = "^[0-9]+[a-z]*$"; //123abc
String content = "abc123abc abc123zxc zxc123abc";
//\\b:匹配目标字符串的边界(以空格划分)
String regStr1 = "abc\\b"; //abc,abc
//\\B:匹配目标字符串的非边界(以空格划分)
String regStr2 = "abc\\B"; //abc,abc
(6)分组和捕获
分组:可以用圆括号组成一个比较复杂的匹配模式,一个圆括号的部分可以看作是一个子表达式/一个分组
捕获:把正则表达式中子表达式/分组匹配的内容,保存到内存中以数字编号或显示命名的组里,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,组0代表的是整个正则式
String content = "asd a1234 aseasf5678asd";
String regStr = "\\d\\d\\d\\d"; //1234,5678
//非命名捕获(pattern)
//1.matcher.group(0) 得到匹配到的字符串
//1.matcher.group(1) 得到匹配到的字符串的第1个分组内容
//1.matcher.group(2) 得到匹配到的字符串的第2个分组内容
String regStr1 = "(\\d\\d)(\\d\\d)"; //1234,12,34,5678,56,78
//命名捕获(?<name>pattern)
//1.matcher.group(0) 得到匹配到的字符串
//1.matcher.group(1) 得到匹配到的字符串的第1个分组内容
//1.matcher.group("name2") 得到匹配到的字符串的第2个分组内容
String regStr2 = "(?<name1>\\d\\d)(?<name2>\\d\\d)"; //1234,12,34,5678,56,78
//非捕获分组(?:pattern):包括d|f
String regStr3 = "as(?:d|f)"; //asd,asf,asd
//非捕获分组(?=pattern):不包括d|f
String regStr4 = "as(?=d|f)"; //as,as,as
//非捕获分组(?!pattern):不包括d|f
String regStr5 = "as(?!d|f)"; //as
(7)反向引用
反向引用:圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部
内部反向引用 \\分组号,外部反向引用 $分组号
String content = "1221,1234,2112";
String regStr = "(\\d)(\\d)\\2\\1"; //1221,2112
String content = "我我爱爱你你";
String regStr = "(.)\\1+"; //我我,爱爱,你你
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
content = matcher.replaceAll("$1");
System.out.println(content); //我爱你
(8)常用方法
String content = "abc 123 abc 你好";
String regStr = "a";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
//matches:整体匹配,返回布尔值
Pattern.matches(regStr,content);
//matches:整体匹配,返回布尔值
matcher.matches();
//输出匹配到的子串开始结束的位置
while (matcher.find()){
System.out.println(matcher.start());
System.out.println(matcher.end());
}
//替换子串并返回
String newContent = matcher.replaceAll("b");
System.out.println(newContent);
(9)String类正则表达式
String content = "ASD#QWE-ZXC~JKL";
//整体匹配
boolean bool = content.matches("[A-Z]{3}");
System.out.println(bool);
//String类方法中的正则表达式:替换
content = content.replaceAll("[AS]","D");
System.out.println(content);
//String类方法中的正则表达式:分割
String[] split = content.split("#|-|~");
for (String s : split) {
System.out.println(s);
}