内部类与异常类
内部类
- Java支持在一个类中定义另一个类,这样的类称作内部类
- 内部类就是外嵌类里定义的一个类型而已
- 外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法
- 内部类的类体中不可以声明类变量和类方法
- 外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员
- public ,protected private 对内部类没有区别,因为内部类仅仅在该外嵌类中可以被使用。
匿名类
•和类有关的匿名类
假设People是类,那么下列代码就是用People的一个子类
(匿名类)创建对象:
new People () {
匿名类的类体
};
匿名类可以继承父类的方法也可以重写父类的方法。使用匿名类时,必然是在某个类中直接用匿名类创建对象,因此匿名类一定是内部类。用匿名类创建对象时,要直接使用父类的某个构造方法。
abstract class Speak {
public abstract void speakHello();
}
class Student {
void f(Speak sp) {
sp.speakHello();
}
}
public class Example6_2 {
public static void main(String args[]) {
Speak speak=new Speak() {
public void speakHello() {
System.out.println("大家好,祝工作顺利!");
}
};
speak.speakHello();
Student st=new Student();
st.f(new Speak() {
public void speakHello() {
System.out.println("I am a student,how are you");
}
});
}
}
•和接口有关的匿名类
Java允许直接用接口名和一个类体创建一个匿名对象,此类体被认为是实现了Computable接口的类去掉类声明后的类体,称作匿名类。
new Computable**()** {
实现接口的匿名类的类****体
};
interface Cubic {
double getCubic(double x);
}
class A {
void f(Cubic cubic) {
double result=cubic.getCubic(3);
System.out.println("result="+result);
}
}
public class Example6_3 {
public static void main(String args[]) {
Cubic cu=new Cubic() {
public double getCubic(double x) {
return x*x*x;
}
};
double m=cu.getCubic(5); //接口回调
System.out.println("m="+m);
A a=new A();
a.f(new Cubic() {
public double getCubic(double x) {
return x*x*x;
}
});
}
}
Lambda表达式
Lambda表达式主要目的是在使用单接口(只含有一个方法的接口)匿名类时让代码更加简洁。
Lambda表达式:
(int a,int b ) -> {
return a+b;
}
interface Cubic {
double getCubic(double x);
}
class A {
void f(Cubic cubic) {
double result=cubic.getCubic(3);
System.out.println("result="+result);
}
}
public class Example6_4 {
public static void main(String args[]) {
Cubic cu=new Cubic() { //和接口有关的匿名类
public double getCubic(double x) {
return x*x*x;
}
};
System.out.println(cu.getCubic(5));
cu= (double x)->{ //使用Lambada表达式简化代码
return x*x*x;
};
System.out.println(cu.getCubic(2));
A a=new A();
a.f((double x)-> { //使用Lambada表达式简化代码
return x*x*x;
});
}
}
异常类
try {
包含可能发生异常的语句
}
catch(ExceptionSubClass1 e) {
…
}
public class IntegerException extends Exception {
String message;
public IntegerException(int m) {
message="年龄"+m+"不合理";
}
public String toString() {
return message;
}
}
public class People {
private int age=1;
public void setAge(int age) throws IntegerException {
if(age>=160||age<=0) {
throw new IntegerException(age); //方法抛出异常,导致方法结束
}
else {
this.age=age;
}
}
public int getAge() {
System.out.println("年龄"+age+"合理");
return age;
}
}
public class Example6_6 {
public static void main(String args[]) {
People wang=new People(),
zhang=new People();
try{ wang.setAge(180);
System.out.println(wang.getAge());
}
catch(IntegerException e) {
System.out.println(e.toString());
}
try { zhang.setAge(37);
System.out.println(zhang.getAge());
}
catch(IntegerException e) {
System.out.println(e.toString());
}
}
}
无论在try部分是否发生过异常,finally子语句都会被执行。
如果在try~catch语句中执行了return语句,那么finally子语句仍然会被执行
try { }
catch(ExceptionSubClass e) { }
finally { }
例子
public class DangerException extends Exception {
final String message = "ГЌжи";
public String warnMess() {
return message;
}
}
public class CargoBoat {
int realContent; //装载的重量
int maxContent; //最大装载量
public void setMaxContent(int c) {
maxContent = c;
}
public void loading(int m) throws DangerException {
realContent += m;
if(realContent>maxContent) {
throw new DangerException();
}
System.out.println("目前装载了"+realContent+"吨货物");
}
}
public class Example6_7 {
public static void main(String args[]) {
CargoBoat ship = new CargoBoat();
ship.setMaxContent(1000);
int m = 600;
try{
ship.loading(m);
m = 400;
ship.loading(m);
m = 367;
ship.loading(m);
m = 555;
ship.loading(m);
}
catch(DangerException e) {
System.out.println(e.warnMess());
System.out.println("无法再装载重量是"+m+"吨的集装箱");
}
finally {
System.out.printf("货船将正点启航");
}
}
}
class类
Java通过使用Class也可以得到一个类的实例
public class Rect {
double width,height,area;
public Rect(){
}
public Rect(double w,double h){
width = w;
height = h;
}
public double getArea() {
area=height*width;
return area;
}
}
public class Example6_8 {
public static void main(String args[]) {
Rect rect = new Rect();
Class cs = rect.getClass(); //或 Class cs = Rect.class;
System.out.println(cs == Rect.class); //输出结果是true
Constructor[] con=cs.getDeclaredConstructors(); //返回类中的构造方法
Field[] field=cs.getDeclaredFields() ; //返回类中的成员变量
Method[] method=cs.getDeclaredMethods(); //返回类中的方法
System.out.println("类的名字:"+className);
System.out.println("类中有如下的构造方法:");
for(int i=0;i<con.length;i++) {
System.out.println(con[i].toString());
}
System.out.println("类中有如下的成员变量:");
for(int i=0;i<field.length;i++) {
System.out.println(field[i].toString());
}
System.out.println("类中有如下的方法:");
for(int i=0;i<method.length;i++) {
System.out.println(method[i].toString());
}
}
}
断言
断言语句在调试代码阶段非常有用,断言语句一般用于程序不准备通过捕获异常来处理的错误,例如,当发生某个错误时,要求程序必须立即停止执行。
- 打开断言
在调试代码阶段让断言语句发挥作用,这样就可以发现一些致命的错误。
- 关闭断言
程序正式运行时就可以关闭断言语句,但仍把断言语句保留在源代码中,如果以后应用程又需要调试,可以重新启用断言语句。
import java.util.Scanner;
public class Example6_10 {
public static void main (String args[ ]) {
System.out.println("请输入正数回车确认");
Scanner scan=new Scanner(System.in);
double number=scan.nextDouble();
assert number>0:"负数不能计算平方根";
System.out.println(number+"的平方根:"+Math.sqrt(number));
}
}