异常类
异常的作用域
public class ExceptionTest2 {
public static void main(String[] args) {
try {
int len = getStrLength(null);
} catch (NullPointerException e) {
}
System.out.println("程序执行到这"+len);
}
// 获取字符串的长度
public static int getStrLength(String str) {
return str.length();
}
}
这段代码会执行失败,是因为 int len
这个变量定义在try的代码块里,要想打印 len
就需要提升作用域 ,就是把变量定义在代码块前面,如下。
public class ExceptionTest2 {
public static void main(String[] args) {
int len = 0;
try {
len = getStrLength(null);
} catch (NullPointerException e) {
}
System.out.println("程序执行到这"+len);
}
// 获取字符串的长度
public static int getStrLength(String str) {
return str.length();
}
}
手动抛出异常
只要在想抛出异常的地方使用throw关键字,使用如下。
public int getInt(String str){
if(str == null){
throw new IllegalArgumentException("姓名不能为空");
}
return Integer.parseInt(str);
}
IllegalArgumentException的父类是RuntimeException,在手工抛出时不需要在方法上约定可能抛出的异常,如果换成Exception,就需要在方法签名上声明它同时一定要调用它,否则就会报错。如下:
public class ExceptionTest7 {
public static void main(String[] args) {
int num = 0;
//调用
try{
num = getInt(null);
}catch(Exception e){
System.out.println(e.getMassage());//获取异常的字符串消息,这里就是“姓名不能为空”
}
System.out.println(num);
}
public static int getInt(String str) throws Exception{//在签名上声明
if(str == null){
throw new Exception("姓名不能为空");//手动抛出
}
return Integer.parseInt(str);
}
}
自定义异常类
创建一个异常类让它继承于Exception就可以了,但是需要注意的是,创建的时候要定义super构造函数,而且也需要创建一个空的构造函数,不然会报错。如下。
public class ParamNullException extends Exception {
public ParamNullException() {
}
public ParamNullException(String msg) {
super(msg);
}
}
内部类
在过去内部类经常用于解决子类只能继承一个父类的缺陷,在Android场景上使用的多一些,但是随着Java的不断升级,其使用场景就越来愈少了。
如下,内部类InnterTool创建在外部类Outer里面。
public class Outer {
public class InnerTool { // 内部类
public int add(int a,int b){
return a+b;
}
}
}
如果想调用内部类,就要先实例化,但是实例化只能在外部类内部,语法和普通类一样,例子如下。
public class OuterUtil {
public class InnerTool { // 内部类
public int add(int a,int b){
return a+b;
}
}
private InnerTool tool = new InnerTool();
}
外部访问内部类,内部类的访问控制修饰符需要时public,而且实例化内部类比较麻烦,不建议,语法如下:
OuterUtil.InnerTool tool = new OuterUtil().new InnerTool();
静态内部类,只需增加static关键字即可,声明为静态内部类后,可以直接调用内部类,不需要先实例化外部类,如下。
package com.youkeda.test;
import com.youkeda.util.OuterUtil;
// 静态内部类是需要单独 import 的
import com.youkeda.util.OuterUtil.InnerTool;
public class OuterUtilTest {
public static void main(String[] args){
InnerTool tool = new InnerTool();
int sum = tool.add(1,2);
System.out.println(sum);
}
}
局部内部类:在方法内部定义一个类,如下。
public class Tester {
public void test(){
class B{
int a;
}
B b = new B();
}
}
匿名类
匿名类可以直接实现接口的实例化。 ```java public class ATest {
public static void main(String[] args){ A a = new A(){
public void method(){
System.out.println("执行内部类");
}
}; a.method(); }
} //A a = new A(){};这个语法等同于下面 public class AImpl implements A{ public void method(){ System.out.println(“执行类”); } }
2. 继承父类
```java
public class Sub {
public void print(){
}
}
public class SubTest {
public static void main(String[] args){
Sub sub = new Sub(){
public void print(){
System.out.println("执行内部类");
}
};
sub.print();
}
}
//相当于
public class SubNode extends Sub {
public void print(){
System.out.println("执行");
}
}
抽象类
Java的继承关系中,抽象类首先时一个父类,实例化必须有子类,如同接口要通过实现类实例化一样。抽象类也可以添加普通方法方便子类复用。
例子如下:
// 定义一个武器的抽象类
public abstract class Weapon{
// 抽象方法:攻击
public abstract void attack();
}
子类必须实现抽象方法。
public class GoldenBar extends Weapon {
public void attack(){
System.out.println("使用金箍棒进行劈一棍");
}
}
接口的默认方法
接口的默认方法,实现类可以不实现(也就是可以覆盖也可以不覆盖),直接调用默认方法
默认方法的语法如下:
public interface Vehicle {
default void print(){
System.out.println("我是一辆车!");
}
}