1.内部类的访问规则:
内部类可以直接访问外部类中的成员,包括私有成员。(因为内部类中有一个外部类的引用 外部类名.this.)
外部类要访问内部类,必须建 立内部类对象。
class Outer { private int x = 3; class Inter { void prin() { System.out.println(x); //这里的x省略了 Outer.this.x } } } //直接访问内部类中的成员 Outer.Inter in = new Outer().new Inter();
访问格式:
2.静态内部类
当内部类在成员位置上,就可以被成员修饰符修饰,如 private 、 static
当内部类被static修饰,只能直接访问外部类中的static成员
在外部其他类中,如何访问静态内部类的非静态成员? new Outer.Inter().function() ;
在外部其他类中,如何访问静态内部类的静态成员? Outer.Inter.function();
当内部类中存在静态成员,该内部类必须是静态的
当外部类中的静态方法访问内部类时,内部类也必须是静态的。
内部类定义在局部时(成员方法内部):不可以被成员修饰符修饰; 可以直接访问外部类中的成员,但不可以访问所在局部的变量,只能访问final修饰的局部变量。
3。匿名内部类: 匿名内部类是内部类的简写格式,它必须继承一个类或者实现接口
格式: new 父类或者接口() { 内容 }.方法名() ;
匿名内部类实质是个匿名子类对象; 匿名内部类对方法只能调用一次
匿名内部类的应用:
interface Inter { void method(); } class Test { static Inter function() { return new Inter() { public void method() { System.out.println("method"); } }; } } class Main { public static void main(String[] args) { //1.Test类中有个静态方法function ,这个方法返回结果是个对象 Test.function().method(); } }
interface Inter { void method(); } class Main { public static void show(Inter in) { in.method(); } public static void main(String[] args) { //2.匿名内部类直接作参数 show(new Inter(){ public void method() { System.out.println("haha"); } }); } }
//3.主函数中的匿名内部类 class InterTest { public static void main(String[] args) { new Object() { public void function(){} }.function(); } }
4.异常 程序运行时出现的问题
问题也是一个具体的事物,可以通过java的类的形式进行描述,并封装成对象。
对于严重的问题,java通过 Error 类进行描述;一般不编写代码进行处理
对于不严重的问题, java通过 Exception 类进行描述。可以使用针对性的处理方式进行处理。
Error类和Exception 类有个共同的父类 Throwable
5。异常的处理:
try{ 需要被检测的代码 ;} catch(异常类){ 处理异常的代码;} finally{ 一定执行的语句 } System.out.println(e.getMessage()); // 异常信息 System.out.println(e.toString());//异常名称 : 异常信息 e.printStackTrace();// 异常名称: 异常信息 异常出现的位置 (JVM默认异常处理机制)
throws Exception
int div (int a)throws Exception //在函数上声明了该函数可能出现问题。凡是调用该函数时,必须try catch 或者同样throws {
。。。。。。
}
6.多异常的处理:
声明异常时,建议声明更具体的异常,这样处理的更具体。
对方声明几个异常,就对应有几个catch块。如果多个catch块中的异常存在继承关系,父类异常catch块放在子类下面(否则编译失败)。
建议在进行catch处理时,catch一定要定义具体处理方式。 一般输出到异常日志中
7.自定义异常:
因为项目中会出现特有的问题,这些问题未被java描述并封装对象,对这些特有的问题,可以进行自定义的封装对象。
必须继承Exception。 因为异常类和异常对象都被抛出,他们具备可抛性。可抛性是Throwable体系独有的特点。
自定义的异常并未定义信息, 需要重写父类的构造函数来写入异常信息。
class FuShuException extends Exception { FuShuException() { } FuShuException(String msg) { super(msg); } } class Demo { int div(int a, int b) throws FuShuException //函数内出现出现throw抛出异常,函数上必须声明,否则编译失败 { if(b<0) throw new FuShuException("fushu"); return a/b; } } class Main { public static void main(String[] args) { Demo d = new Demo(); try { int x = d.div(3,-6); } catch(Exception e) { System.out.println(e.toString()); } } }
throw 与 throws的区别:
throw 定义在函数内,,throws定义在函数上;
throw后跟的是异常对象,throws后面跟的是异常类,可以跟多个,逗号隔开。
8. 运行时异常。 Exception中一个特殊的子类异常 RuntimeException
如果函数内抛出此异常,函数上不用声明,编译也可通过;
如果函数上声明此异常,调用者可以不进行处理,编译通过。
之所以不用在函数声明,是因为不需要调用者处理,当该异常发生,希望程序终止。
自定义异常时,如果该异常发生,无法继续进行运算,就让自定义异常继承 RuntimeException 类
异常分为2类:
编译时被检测的异常;
编译时不被检测的异常(运行时异常,RuntimeException类及其子类)
9. finally 代码块
定义了一定会被执行的代码,通常用于关闭资源。
即使catch块中有return语句,也会执行finally
只有一种情况不执行,当catch语句中有 System.exit(0); 时,finally代码块不执行。
10.异常处理语句有3种格式:
catch是处理异常的,没有catch块就代表异常没有处理,必须声明
try{} catch() {} finally {} try{} catch() {} try{} finally {}
11. 异常在子父类覆盖中的体现:
子类在覆盖父类时,如果父类方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
如果父类方法抛出多个异常,那么子类覆盖该方法时,只能抛出父类异常的子集。
如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类发生异常,必须 try 处理。
12. 异常总结:
异常时对问题的描述,将问题进行对象封装。
Throwable
|--Error Exception
异常体系的特点: 异常体系中的所有类已经建立的对象都具有可抛性,也就是可以被throw throws操作。
throw定义在函数内,用于抛出异常对象; throws定义在函数上,用于抛出异常类。
当函数内有throw抛出异常对象,并未进行try处理,必须在函数上声明,否则编译失败。 RuntimeException类除外
如果函数声明了异常,调用者需要进行处理。可以throws,也可以try
异常有2种:
编译时异常
运行时异常(编译时不检测)
自定义异常: 继承Exception 或 RuntimeException 使该类具备可抛性,具备操作异常的共性方法。
异常信息传递给父类的构造函数 super(String message);
异常的好处: 将问题封装
将正常流程代码和问题处理代码分离,方便于阅读。
异常的处理原则: 处理方式有2种: try 或者 throws
调用抛出异常的函数时,抛出几个,就处理几个,一个try对应多个catch, 父类的catch放在下面(否则编译失败!)
catch内,需要定义针对性的处理方式。当捕获的异常处理不了时,可以在catch块中继续抛出,或将异常转换后抛出相关异常
13. 包 package
包用来对类文件进行分类管理, 给类提供多层命名空间,写在程序第一行。 包也是一种封装形式。
类的全称: 包名.类名
包名:多单词组成时所有字母小写
访问其他包里的方法时,被访问包里的类和类中的成员都必须是被public修饰的。
不同包中的子类可以访问父类中被protected修饰的成员
package packb; public class DemoB { protected void method() { System.out.println("B运行了"); } } package packa; public class DemoA extends packb.DemoB //继承不同包里的类时,DemoB必须被public修饰,否则编译失败! { public void show() { System.out.println("A运行了"); method(); //不同包的子类,成员被public或protected修饰,可以直接访问 } } //一个java文件,只允许存在最多1个被public修饰的类 package pack; class PackDemo { public static void main(String [] args) { //packb.DemoB b = new packb.DemoB(); //b.method(); //编译失败,无法访问protected修饰的成员 packa.DemoA a = new packa.DemoA(); a.show(); } }
访问权限总结:
public | protected | default | private | |
同一类 | ok |
ok |
ok | ok |
同一包 | ok | ok | ok | |
不同包的子类 | ok | ok | ||
不同包非子类 | ok |
JVM在寻找并运行class文件时,先搜索classpath,在搜索当前目录。
set classpath=路径1;路径2 会先找路径1,再找路径2,当前路径用 . 表示
为了简化类名的书写,使用关键字 import , 导入的是包中的类
import pack1.pack2.Demo; //导入 Demo 类 import pack1.pack2.* ; //导入pack2文件夹下所有的类
eclipse中Ctrl+Shift+M 添加类的import导入
Ctrl+Shift+O 组织类的import导入(既有Ctrl+Shift+M的作用,又可以帮你去除没用的导入,很有用)