Java复习篇二

从天津转站北京,爬到中关村到直立行走
Java复习篇二
四种形式的的类:
成员式:静态内部类:静态类中的内部类,调用外部类的私有属性和方法。
成员内部类:外部类对象和内部类对象(即外部类对象的引用,1对多的关系)
OuterA outer = new OurterA();
OuterA.InnerB innb = OuterA.new InnerB();
局部式:局部内部类:
匿名内部类
为什么要用内部类:1)某类中访问另外一个类中的私有类。
  2)某一个类中的对象依赖于另一个类的对象。
代码部分:
package Javamodel;
/**
* 区分内部类中的成员式:静态内部类和成员内部类的区别
* @author xinglefly
* @version 1
*/
public class InnerClass2 {

public static void main(String [] args){
InnerOut.InnerA innA = new InnerOut.InnerA();
innA.moveA();

InnerOut out = new InnerOut();
InnerOut.InnerB innB = out.new InnerB();
innB.moveB();
}
}


class InnerOut{
private static String str1="hehe";
private String str2="xinglefly";

public static void m1(){
System.out.println("static function");
}

public void m2(){
System.out.println("non-static function");
}

//静态内部类  (静态代码块)
static class InnerA{
private static String str1="static innerA";
private String str2="ineerA str2";
public static void moveA(){
//只能调用外部内的静态变量,不能调用非静态属性
System.out.println(InnerOut.str1);
System.out.println(str1);
InnerOut.m1();
//m2();
}
}

//成员内部类 需要有外部的成员对象才能生成内部的对象
class InnerB{
//内部类对象的引用,1对多的关系
String str1="static innerA";
String str2="ineerA str2";
public void moveB(){
//可以访问外部的所有成员
System.out.println(InnerOut.str1);
System.out.println(InnerOut.this.str2);
m1();
m2();

}
}
}

局部类通过接口的回调
package Javamodel;

/**
* 局部内部类
* @author xinglefly
* @version 1
*/
public class InnerClass3 {

public static void main(String[] args){
OutB outer = new OutB();
MyInter my = outer.outerM();//接口的回调
my.m1();
my.m2();
}
}

class OutB{
String str1="hello";

public MyInter outerM(){
int i=10;
final int j=20;

//局部内部类
class InnerC implements MyInter{

public void m1() {
System.out.println("innerc m1");
}

public void m2() {
System.out.println("innerc m2");
}
}//innerc  end
return new InnerC();
}//outerM() end
}

interface MyInter{
public void m1();
public void m2();
}

------------------------------
package Javamodel;
/**
* 匿名内部类:
* @author xinglefly
* @version 1
*/
public class InnerClass4 {

//遵循两个原理:1.定义一个类,实现或者继承MyInter,并按照大括号中的方式实现或者覆盖接口中的方法
//2.生成一个该类的对象,特殊的局部内部类。
public static void main(String[] args){
method(new MyInter(){
public void m1(){
System.out.println("m1()");
}
public void m2(){
System.out.println("m2()");
}
});
}

public static void method(MyInter myi){
myi.m1();
myi.m2();
}
}

class OouterC{
public MyInter outerM(){
return new MyInter(){
public void m1(){

}
public void m2(){

}
};
}//outerM end
}

依照上面内部类的分类继续需要注意事项(由浅入深)

内部类:
(注:所有使用内部类的地方都可以不用内部类,使用内部类可以使程序更加的简洁,便于命名规范和划分层次结构)。
内部类是指在一个外部类的内部再定义一个类。
内部类作为外部类的一个成员,并且依附于外部类而存在的。
内部类可为静态,可用PROTECTED和PRIVATE修饰。(而外部类不可以:外部类只能使用PUBLIC和DEFAULT)。

成员内部类:作为外部类的一个成员存在,与外部类的属性、方法并列。
内部类和外部类的实例变量可以共存。
在内部类中访问实例变量:this.属性
在内部类访问外部类的实例变量:外部类名.this.属性。

成员内部类的优点:
⑴内部类作为外部类的成员,可以访问外部类的私有成员或属性。(即使将外部类声明为PRIVATE,但是对于处于其内部的内部类还是可见的。)
⑵用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。
注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。
对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。
成员内部类不可以有静态属性。(为什么?)

如果在外部类的外部访问内部类,使用out.inner.

建立内部类对象时应注意:
在外部类的内部可以直接使用inner s=new inner();(因为外部类知道inner是哪个类,所以可以生成对象。)
而在外部类的外部,要生成(new)一个内部类对象,需要首先建立一个外部类对象(外部类可用),然后在生成一个内部类对象。
Outer.Inner in=Outer.new.Inner()。
错误的定义方式:
Outer.Inner in=new Outer.Inner()。
注意:当Outer是一个private类时,外部类对于其外部访问是私有的,所以就无法建立外部类对象,进而也无法建立内部类对象。

局部内部类:在方法中定义的内部类称为局部内部类。
与局部变量类似,在局部内部类前不加修饰符public和private,其范围为定义它的代码块。

注意:局部内部类不仅可以访问外部类实例变量,还可以访问外部类的局部变量(但此时要求外部类的局部变量必须为final)??
在类外不可直接生成局部内部类(保证局部内部类对外是不可见的)。
要想使用局部内部类时需要生成对象,对象调用方法,在方法中才能调用其局部内部类。

静态内部类:(注意:前三种内部类与变量类似,所以可以对照参考变量)
静态内部类定义在类中,任何方法外,用static定义。
静态内部类只能访问外部类的静态成员。
生成(new)一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成:
Outer.Inner in=new Outer.Inner();
而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类。
静态内部类不可用private来进行定义。例子:
对于两个类,拥有相同的方法:


匿名内部类(必须掌握):
匿名内部类是一种特殊的局部内部类,它是通过匿名类实现接口。
IA被定义为接口。
IA I=new IA(){};
注:一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类,没有类名,根据多态,我们使用其父类名。
因其为局部内部类,那么局部内部类的所有限制都对其生效。
匿名内部类是唯一一种无构造方法类。
匿名内部类在编译的时候由系统自动起名Out$1.class。

如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口的类。
因匿名内部类无构造方法,所以其使用范围非常的有限。


//数组
1.定义数组;
2.数组实例化;
3.数组赋值;
4.循环访问数组;
int[] arr;声明 并没有非配空间
arr = new int[5];分配空间,new 相当于指向了它的空间

1.声明:int[] arr;
2.实例化:arr = new Int[5];
1.2合并:int[] arr = new int[5];
声明实例化、赋值合并;
int 【】 arr = new int[]{10,20,30,40,50};
int 【】 arr = {10,20,30,40,50}; //声明的赋值只有这样放在一行
int arr[];数组必须为空
for(int i = 0;i < arr.length; i++)
-----------------------
int 【】【】 arr;
arr  = new int【3】【5】;
arr  = new int【3】【】;
arr【0】= new int 【5】;
arr【1】= new int【3】;对象的引用

int 【】【】 arr ={{1,2,3},{4,5},{6,7}};

for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){

}
}

-----------------------数组的拷贝
System.arraycopy();
int myArray[] ={1,2,3,4,5,6};
int hold[] = {10,9,8,7,6,5,4,3,2,1};
System.arraycopy(myArry,0,hold,0,myArry.length);hold(目标数组名),0{目标数组接收元素的开始位置}myArray.length拷贝的长度


Exception
异常由来:问题就是现实生活中一个具体的食物,也可以通过java的类的形式进行描述,并封装成对象。
对于问题的划分:
两种:一种是要严重问题(Error类)
另一种是严重问题 (Exception)
Exception中有一个特殊的子类异常RuntimeException运行时异常。
如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过。
如果在函数上声明了该异常,调用者可以不用进行处理。
编辑时被检测的异常。(没有处理,也有抛出没try,编辑失败)
(该异常被标识,代表可以被处理)
运行时不被检测的异常,RuntimeException以其子类。
      在编译时,不需要处理,编译器不检查。
    该异常发生,建议不处理,让程序停止,对代码进行修正。
  Catch代表的处理异常。
问题代码和处理代码相分离。


对于程序可能出现的错误应该做出预案。
例外是程序中所有出乎意料的结果。(关系到系统的健壮性)

JAVA会将所有的错误封装成为一个对象,其根本父类为Throwable。
Throwable有两个子类:Error和Exception。
一个Error对象表示一个程序错误,指的是底层的、低级的、不可恢复的严重错误。此时程序一定会退出,因为已经失去了运行所必须的物理环境。
对于Error错误我们无法进行处理,因为我们是通过程序来应对错误,可是程序已经退出了。
我们可以处理的Throwable对象中只有Exception对象(例外/异常)。
Exception有两个子类:Runtime exception(未检查异常)
非Runtime exception(已检查异常)
(注意:无论是未检查异常还是已检查异常在编译的时候都不会被发现,在编译的过程中检查的是程序的语法错误,而异常是一个运行时程序出错的概念。)
在Exception中,所有的非未检查异常都是已检查异常,没有另外的异常!!

未检查异常是为程序员没有进行必要的检查,因为他的疏忽和错误而引起的异常。一定是属于虚拟机内部的异常(比如空指针)。

应对未检查异常就是养成良好的检查习惯。
已检查异常是不可避免的,对于已检查异常必须实现定义好应对的方法。
已检查异常肯定跨越出了虚拟机的范围。(比如“未找到文件”)

如何处理已检查异常(对于所有的已检查异常都要进行处理):
首先了解异常形成的机制:
当一个方法中有一条语句出现了异常,它就会throw(抛出)一个例外对象,然后后面的语句不会执行返回上一级方法,其上一级方法接受到了例外对象之后,有可能对这个异常进行处理,也可能将这个异常转到它的上一级。
对于接收到的已检查异常有两种处理方式:throws和try方法。

注意:出错的方法有可能是JDK,也可能是程序员写的程序,无论谁写的,抛出一定用throw。


例:public void print() throws Exception.

对于方法a,如果它定义了throws Exception。那么当它调用的方法b返回异常对象时,方法a并不处理,而将这个异常对象向上一级返回,如果所有的方法均不进行处理,返回到主方法,程序中止。(要避免所有的方法都返回的使用方法,因为这样出现一个很小的异常就会令程序中止)。

如果在方法的程序中有一行throw new Exception(),返回错误,那么其后的程序不执行。因为错误返回后,后面的程序肯定没有机会执行,那么JAVA认为以后的程序没有存在的必要。

Throwable:
Exception可以控制的异常
RuntimeException 运行时异常
ArithneeticException 算术运算错误
ArrayIndexOutofBounds 数组索引值错误
ArrayStoreException 赋给数组实例错误
ClassCastException 类型转换
IntgalArgumentException方法参数传递
NativeArraySizeException声明数组的大小为负值
NullPointException 未赋给对象实例的对象
SecurityException 违反安全性限制
  Error无法控制的错误情况
outofMemoryError
StackOverFlowError
UnknownError
AWTError
ThreadDeath
CheckException外在因素
classNotFoundException 程序运行时,找不到所需文件
FileNotFoundException 找不到制定文件
InterrupedException 运行时中断
IOException 输入输出处理错误(网络,文件等)
SqlException 数据库处理错误

异常的好处:
将问题进行封装
将正常流程代码和问题代码相分离,方便于阅读。

处理原则:
处理方式有两种,try或throws
调用抛出异常的功能时,抛出几个处理几个,一个try对应多个catch
Catch内需要定义针对性的处理方式,不要简单的定义printStackTrace输出语句。

注意事项:
子类抛出异常必须是父类的异常子类或子集。
如果父类或者接口没有异常抛出,子类覆盖出现异常,只能try,不能抛

关于Throws和throw
Throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。
Throw定义在函数内,用于抛出异常对象,并进行try处理。除RuntimeException除外,如果抛出异常,函数上可以不用声明。


对于try……catch格式:
try  {可能出现错误的代码块}   catch(exception e){进行处理的代码} ;
                                对象变量的声明

用这种方法,如果代码正确,那么程序不经过catch语句直接向下运行;
如果代码不正确,则将返回的异常对象和e进行匹配,如果匹配成功,则处理其后面的异常处理代码。(如果用exception来声明e的话,因为exception为所有exception对象的父类,所有肯定匹配成功)。处理完代码后这个例外就完全处理完毕,程序会接着从出现异常的地方向下执行(是从出现异常的地方还是在catch后面呢?利用程序进行验证)。最后程序正常退出。

Try中如果发现错误,即跳出try去匹配catch,那么try后面的语句就不会被执行。
一个try可以跟进多个catch语句,用于处理不同情况。当一个try只能匹配一个catch。
我们可以写多个catch语句,但是不能将父类型的exception的位置写在子类型的excepiton之前,因为这样父类型肯定先于子类型被匹配,所有子类型就成为废话。JAVA编译出错。

在try,catch后还可以再跟一子句finally。其中的代码语句无论如何都会被执行(因为finally子句的这个特性,所以一般将释放资源,关闭连接的语句写在里面)。


如果在程序中书写了检查(抛出)exception但是没有对这个可能出现的检查结果进行处理,那么程序就会报错。
而如果只有处理情况(try)而没有相应的catch子句,则编译还是通不过。
如何知道在编写的程序中会出现例外呢
调用方法,查看API中查看方法中是否有已检查错误。
在编译的过程中看提示信息,然后加上相应的处理。

Exception有一个message属性。在使用catch的时候可以调用:
Catch(IOException e){System.out.println(e.message())};
Catch(IOException e){e.printStackTrace()};
上面这条语句回告诉我们出错类型所历经的过程,在调试的中非常有用。


开发中的两个道理:
①如何控制try的范围:根据操作的连动性和相关性,如果前面的程序代码块抛出的错误影响了后面程序代码的运行,那么这个我们就说这两个程序代码存在关联,应该放在同一个try中。
对已经查出来的例外,有throw(积极)和try catch(消极)两种处理方法。
对于try catch放在能够很好地处理例外的位置(即放在具备对例外进行处理的能力的位置)。如果没有处理能力就继续上抛。

当我们自己定义一个例外类的时候必须使其继承excepiton或者RuntimeException。
Throw是一个语句,用来做抛出例外的功能。
而throws是表示如果下级方法中如果有例外抛出,那么本方法不做处理,继续向上抛出。
Throws后跟的是例外类型。

断言是一种调试工具(assert)
其后跟的是布尔类型的表达式,如果表达式结果为真不影响程序运行。如果为假系统出现低级错误,在屏幕上出现assert信息。
Assert只是用于调试。在产品编译完成后上线assert代码就被删除了。

方法的覆盖中,如果子类的方法抛出的例外是父类方法抛出的例外的父类型,那么编译就会出错:子类无法覆盖父类。
结论:子类方法不可比父类方法抛出更多的例外。子类抛出的例外或者与父类抛出的例外一致,或者是父类抛出例外的子类型。或者子类型不抛出例外。
如果父类型无throws时,子类型也不允许出现throws。此时只能使用try catch。

package com.xinglefly.java.test;

import java.sql.SQLException;

/**
* finally代码块:定义一定执行代码。通常用于关闭资源
* @author xinglefly
* @version 1
*/
class Demo1{
public int div(int i,int j)throws FushuException{
if(j<0)
throw new FushuException("不能为负数");
return i/j;
}

public void method()throws noException{
try{
System.out.println("连接数据库");
System.out.println("数据操作");
}catch(Exception e){
System.out.println("会对数据进行异常处理");
throw new noException("不想说");
}finally{
System.out.println("关闭数据库");
}
}
}

public class Exception2 {
public static void main(String[] args){
Demo1 d = new Demo1();
try{
int x = d.div(4, -1);
System.out.println("x="+x);
d.method();
}catch(Exception e){
System.out.println(e.toString());
return;//return 语句是执行函数,如果执行后返回主函数,不执行over
}finally{
System.out.println("一定会被执行代码");
}

System.out.println("over");
}
}

class FushuException extends Exception{
public FushuException(String msg) {
super(msg);
}
class noException extends Exception{
public noException(String msg) {
super(msg);
}
}

}

-----
package Javamodel;

/**
* 异常就是程序在运行时出现不正常情况
* 异常由来:问题就是现实生活中,一个具体的食物,也可以通过java类的形式进行描述,并封装成对象
* 对于问题的划分:两种:一种是要重问题,一种非严重问题。
* Exception 中有一个特殊的异常RuntimeException运行异常,如果在函数内容抛出该异常,函数上可以不用声明编译一样通过
* 1.编译时被检测的异常
* 2.运行时不被检测异常,RuntimeException以及其子类
* @author xinglefly
* @version 1
*/
class DemoTest{

//如果函数抛出异常,就需要处理异常try catch
int div(int i,int j) throws Exception{//在功能上通过throws关键字声明该功能有可能会显现问题
return i/j;
}

int div1(int i,int j)throws ArithmeticException{
// 父类runtimeException
        //if(j==0)throw new ArithmeticException("被零整除了");
return i/j;
}
}

class Personp{
public void checkName(String name){
//if(name.equals("lili")){//NullPointerException
if("lili".equals(name)){//name.equals(null)&&name.equals("lili")
System.out.println("yes");
}else{
System.out.println("no");
}
}
}

public class ExceptionTest {

public static void main(String [] aegs){
DemoTest d = new DemoTest();
Personp p = new Personp();
p.checkName(null);
p.checkName("lili");


try{
int x = d.div(4, 0);
System.out.println("x="+x);
}catch(Exception e){//Exception e = new ArithmeticException();多态
//给出预先处理的方式
System.out.println("除数不能为0");
System.out.println(e.getMessage());//by zero
System.out.println(e.toString());//类名 异常信息
e.printStackTrace();//类名 异常信息 错误出处
}finally{
System.out.println("div is over!");
}
}
}

猜你喜欢

转载自xinglefly.iteye.com/blog/1673149