异常类分两大类型:Error类代表了编译和系统的错误,不允许捕获;Exception类代表了标准Java库方法所激发的异常。Exception类还包含运行异常类Runtime_Exception和非运行异常类Non_RuntimeException这两个直接的子类。
运行异常类对应于编译错误,它是指Java程序在运行时产生的由解释器引发的各种异常。运行异常可能出现在任何地方,且出现频率很高,因此为了避免巨大的系统资源开销,编译器不对异常进行检查。所以Java语言中的运行异常不一定被捕获。出现运行错误往往表示代码有错误,如:算数异常(如被0除)、下标异常(如数组越界)等。
非运行异常时Non_RuntimeException类及其子类的实例,又称为可检测异常。Java编译器利用分析方法或构造方法中可能产生的结果来检测Java程序中是否含有检测异常的处理程序,对于每个可能的可检测异常,方法或构造方法的throws子句必须列出该异常对应的类。在Java的标准包java.lang java.util 和 java.net 中定义的异常都是非运行异常。
常见的异常类
1.算术异常类:ArithmeticExecption
出现异常的运算条件时,会出现此异常
packet TestArithmeticException;
public class TestArithmeticException {
public static void main(String[] args) {
Integer temp = 1;
try {
System.out.println(temp/0);
} catch (ArithmeticException e) {
e.printStackTrace();
}
}
}
/**
*输出
*java.lang.ArithmeticException: / by zero
at TestArithmeticException.TestArithmeticException.main(TestArithmeticException.java:6)
*/
2.空指针异常类:NullPointerException
一般报Java.lang.NullPointerException的原因有以下几种:
(1)字符串变量未初始化
(2)对象没有用具体的类初始化
package TestNullPointException;
public class TestNullPointException {
public static void main (String[] args) {
String str = null;
try {
if (str.equals(null)) {
System.out.println("true");
} else {
System.out.println("false");
}
} catch (NullPointException e) {
e.printStackTrace();
}
}
}
/**
*输出:
*java.lang.NullPointerException
at TestNullPointException.TestNullPointException.main(TestNullPointException.java:6)
*/
3.类型强制转换异常:ClassCastException
package test;
public class ExceptionTest {
public static void main(String[] args) {
Object obj=new Object();
Integer s=(Integer)obj;
}
}
/**
*输出:
*Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.Integer
at test.ExceptionTest.main(ExceptionTest.java:5)
*/
4.数组下标越界异常:ArrayIndexOutOfBoundsException
当引用的索引值超出数组长度时,就会发生此异常。
package TestArrayIndexOutOfBoundsException;
public class TestArrayIndexOutOfBoundsException {
public static void main (String[] args) {
Integer[] array = new Integer[10];
try {
Integer temp = array[10];
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
}
}
/**
*输出:
*java.lang.ArrayIndexOutOfBoundsException: 10
atTestArrayIndexOutOfBoundsException.TestArrayIndexOutOfBoundsException.main(TestArrayIndexOutOfBoundsException.java:6)
*/
5.字符串转换为数字异常:NumberFormatException
package test;
public class ExceptionTest {
public static void main(String[] args) {
String s = "q12";
Integer i = Integer.parseInt(s);
}
}
/**
*输出:
*Exception in thread "main" java.lang.NumberFormatException: For input string: "q12"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at test.ExceptionTest.main(ExceptionTest.java:8)
*/
6.类型强制转换异常:ClassCastException
通常是进行强制类型转换时候出现的错误
package test;
public class ExceptionTest {
public static void main(String[] args) {
Object obj=new Object();
Integer s=(Integer)obj;
}
}
/**
*输出:
*Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.Integer
at test.ExceptionTest.main(ExceptionTest.java:5)
*/
7.数组负下标异常:NegativeArrayException
8.违背安全原则异常:SecturityException
9.文件已结束异常:EOFException
10.文件未找到异常:FileNotFoundException
11.输入输出异常:IOException
异常类还有很多,这里就不进行列举了。
(1)object类的概念
类Object是类层次结构的根,也就是说任何类都是该类的直接或间接子类。
如果定义一个java类时没有使用extends关键字声明其父类,则其父类为Object类。
Object类定义了“对象”的基本行为,被子类默认继承。
(2)object类的常用方法
boolean equals(Object) 比较两个对象是否相等。默认比较的是地址值。
Class getClass() 返回一个对象运行时的实例类
int hashCode() 返回该对象的散列码值
void notify() 激活等待在该对象的监视器上的一个线程
void notifyAll() 激活等待在该对象的监视器上的全部线程
String toString() 返回该对象的字符串表示
boolean->Boolean
char->Character
byte->Byte
short->Short
int->Integer
long->Long
float->Float
double->Double
包装类的意义:
让基本数据类型有面向对象的特征;
封装了字符串转化成基本数据类型的方法
包装类的常用方法:Integer.parseInt(),Long.paseLong(),Double.parseDouble()
math类的方法都是静态方法,可以直接引用
常用的数学类方法:
abs() | 获取绝对值 |
max() | 求最大值 |
min() | 求最小值 |
pow() | 求次幂 |
round() | 四舍五入 |
sqrt() | 求平方根 |
Java常用时间类:Date 日期类,Calendar 日历类,SimpleDateFormat格式化时间类
(1)Date日期
new Date() 可以获取到系统时间
getTime() 能获取到时间的long形式,可以用来计算时间差
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date d = new Date();
System.out.println(d); // 系统时间
//get...()——获取年月日.....
System.out.println(d.getYear()+1900); // 从1900年开始算的
System.out.println(d.getMonth()+1); // 月份从0开始计算
System.out.println(d.getDate()); // 天数
System.out.println(d.getHours());// 小时
//getTime()——获取到时间的毫秒形式 返回的是long
System.out.println(d.getTime());
}
}
(2)Calendar 日历
get() 获取到时间的某一部分
set() 设置时间 - -> 计算时间:系统已经帮我们设置好了,不用担心二月有多少天等问题,计 算时间十分方便
(3)SimpleDateFormat格式化时间
Date,Calendar通过引用也可以进行时间的格式化,但比较繁琐,而SimpleDateFormat类是专门帮我们格式化时间的工具类,它在java.text包中。
两种常用方法:
format(Date) 帮我们把时间转成字符串,字符串的格式为SimpleDateFormat类定义对象时设置的时间格式
parse(String) 帮我们把字符串转化成时间
字符串类常用方法汇总
修饰符和返回值的类型 | 方法名 | 解释 |
char | charAt() | 获取某个位置的字符 |
String | concat() | 字符串的拼接 |
boolean | contains() | 判断原字符串是否含有***字符串 |
boolean | endsWith() | 判断原字符串是否以***字符串结尾 |
boolean | startsWith() | 判断原字符串是否以***字符串开头 |
boolean | equals | 判断两边字符串内容是否相同;==判断地址是否相同 |
boolean | equalsIgnoreCase() | 忽略大小写判断两边字符串的内容是否一样 |
int | indexOf() | 计算给出字符串第一个出现的位置 |
int | LastindexOf() | 计算给出字符串最后一个出现的位置 |
int | length() |
计算字符串的长度 |
String | replace() | 字符串内容的替换 |
String[] | split() |
字符串切割,最后结果是一个字符数组 |
String | substring() | 字符串截取,左闭右开 |
String | trim() | 去掉字符串左右两边的空格 |
static String | valueOf() | 基本数据类型转为字符串操作 |
String类的缺点:
String 是一个不可变的数据类型,每每拼接都会产生一个新的字符串,那么内存迟早会被这些拼接的字符串塞满。
String类和StringBuilder和StringBuffer类的区别:
StringBuilder和StringBuffer:可变的字符串,不产生新对象,比较省内存,当进行大量的字符串拼接时建议使用StringBuffer和StringBuilder,但它们两个一些方法的实现几乎跟String一样。
StringBuffer和StringBuilder类:
相似点:
两者用法一模一样,可以认为是一个类
区别:
StringBuffer线程安全,StringBuilder非线程安全。
StringBuilder相比于StringBuffer有速度优势,多数情况下建议使用StringBuilder类,但当被要求线程安全时必须使用StringBuffer类。
Java容器分为collection和map两大类,其下又有很多子类
Collection
List
ArrayList
LinkedList
Vector
Stack
Set
HashSet
LinkedHashSet
TreeSet
Map
HashMap
LinkedHashMap
TreeMap
ConcurrentHashMap
Collection: 存放独立元素的序列。
Map:存放key-value型的元素对。
List,Set,Map之间的区别:
List:有序集合,元素可重复
Set:不重复集合,LinkedHashSet按照插入排序,SortedSet可排序,HashSet无序
Map:键值对集合,存储键、值和之间的映射;Key无序,唯一;value 不要求有序,允许重复
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,即给类型指定一个参数,然后在使用时再指定此参数具体的值,那样这个类型就可以在使用时决定了。这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
保证了类型的安全性。
public static void useGeneric() {
ArrayList names = new ArrayList<>();
names.add("mikechen的互联网架构");
names.add(123); //编译不通过
}
消除强制转换:泛型的一个附带好处是,消除源代码中的许多强制类型转换,这使得代码更加可读,并且减少了出错机会。
List list = new ArrayList();
list.add("hello");
String s = list.get(0); // no cast
避免了不必要的装箱,拆箱操作,提高程序的性能。
提高代码的重用性。
(1)泛型类
泛型类型必须是引用类型(非基本数据类型),定义泛型类,在类名后添加一对尖括号,并在尖括号中填写类型参数,参数可以有多个,多个参数使用逗号分隔。
public class GenericClass {
private T value;
public GenericClass(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
(2)泛型接口
把泛型定义在方法上
方法声明中定义的形参只能在该方法里使用,而接口、类声明中定义的类型形参则可以在整个接口、类中使用。当调用fun()方法时,根据传入的实际对象,编译器就会判断出类型形参T所代表的实际类型。
public interface GenericInterface {
void show(T value);}
}
public class StringShowImpl implements GenericInterface {
@Override
public void show(String value) {
System.out.println(value);
}}
public class NumberShowImpl implements GenericInterface {
@Override
public void show(Integer value) {
System.out.println(value);
}}
(3)泛型方法
是在调用方法的时候指明泛型的具体类型。
/**
*
* @param t 传入泛型的参数
* @param 泛型的类型
* @return T 返回值为T类型
* 说明:
* 1)public 与 返回值中间非常重要,可以理解为声明此方法为泛型方法。
* 2)只有声明了的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
* 3)表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
* 4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E等形式的参数常用于表示泛型。
*/
public T genercMethod(T t){
System.out.println(t.getClass());
System.out.println(t);
return t;
}
public static void main(String[] args) {
GenericsClassDemo genericString = new GenericsClassDemo("helloGeneric"); //这里的泛型跟下面调用的泛型方法可以不一样。
String str = genericString.genercMethod("hello");//传入的是String类型,返回的也是String类型
Integer i = genericString.genercMethod(123);//传入的是Integer类型,返回的也是Integer类型
}
class java.lang.String
hello
class java.lang.Integer
123
(1)无边界的通配符(Unbounded Wildcards), 就是>, 比如List>
无边界的通配符的主要作用就是让泛型能够接受未知类型的数据.
(2)固定上边界的通配符(Upper Bounded Wildcards),采用 extends E>的形式
使用固定上边界的通配符的泛型, 就能够接受指定类及其子类类型的数据。
要声明使用该类通配符, 采用 extends E>的形式, 这里的E就是该泛型的上边界。
注意: 这里虽然用的是extends关键字, 却不仅限于继承了父类E的子类, 也可以代指显现了接口E 的类。
(3) 固定下边界的通配符(Lower Bounded Wildcards),采用 super E>的形式
使用固定下边界的通配符的泛型, 就能够接受指定类及其父类类型的数据.。
要声明使用该类通配符, 采用 super E>的形式, 这里的E就是该泛型的下边界.。
注意: 你可以为一个泛型指定上边界或下边界, 但是不能同时指定上下边界。