一、 Java SE 开篇
1. Java 基本数据类型及其对应的包装类
基本数据类型 对应的包装类 * byte Byte * boolean Boolean * char Character * int Integer * long Long * short Short * float Float * double Double
1.2 自动装箱和自动拆箱
// 1.自动装箱: // 基本类型自动封装到对应的包装类对象中,如: Integer i = 100; // 本质上编译器编译时添加了: Integer i = new Integer(100); // 2.自动拆箱: // 包装类对象自动转换成对应的基本类型数据,如: int a = new Integer(100); // 本质上编译器编译时添加了: int a = new Integer(100).intValue();
2. Java 封装
同一个类 同一个包 子类 所有类 private √ default √ √ protected √ √ √ public √ √ √ √ 封装要点: * 1.属性成员一般使用 private * 2.提供相应的 getter/setter 方法来访问相关属性,这些方法通常是 public(注意:boolean 变量的 getter 方法是用: is 开头!) * 3.只用于本类的辅助性方法用 private,希望其他类能够调用的方法使用 public
3. 关键字
1. static 用于声明静态方法和静态成员 注意:在 static 方法中可直接访问 static 声明的成员;不可以直接访问非 static 的成员,只能先实例化对象才能进行访问! 2. final 通常用于声明常量 注意:不能继承用 final 修饰的类,不能对用 final 定义的方法进行重写! 3. this 调用本类中的属性和方法 注意:this 不建议用于调用本类中用 static 声明的属性和方法上; this();必须位于重载的构造方法中的第一句,来调用无参构造器! 4. super 是对直接父类对象的引用。可以通过 super 来访问父类中被子类覆盖的方法和属性。任何类的构造函数中,Java 默认都会调用 super(); 注意:super(); 必须位于子类构造方法的第一句! 5. instanceof 用于判断一个对象是否是指定类的一个实例,用法:boolean ins = object instanceof class; 注意:object 必须是对象的引用,不能是基本数据类型
4. 构造器
构造器,又称构造方法,是一种特殊的方法 * 格式:public + 类名(){} * 1.通过 new 关键字调用 * 2.构造方法名必须和类名一致! * 3.作用:构造该类的对象,经常用来初始化对象的属性 * 4.不能定义返回值类型,也不能在里面使用 return
* 5.构造方法也可以重载
5. 抽象类
抽象类 abstract,为所有子类提供一个通用的模板 * 要点: * 1.含有抽象方法的类一定是抽象类,所以在定义时必须定义成抽象类! * 2.抽象类不能实例化,即不能用 new 来实例化抽象类 * 3.抽象类只能用来被继承 extends * 4.抽象方法必须通过子类重写 * 5.抽象类中可以包含属性,非抽象方法,构造方法等
* 6.声明抽象方法不可写出大括号 public abstract class Animal { public static final int MIN_VALUE = 100; private String name; public abstract void fun(); public Animal(){ System.out.println("创建一个动物对象"); } public void hello(){ System.out.println("hello,abstract!"); } }
6. 接口
接口 interface * 接口比抽象类更加的“抽象”,意义在于规范设计和实现代码分离 * 接口中只有:常量,抽象方法! * 接口能被子类实现 implements * 普通类只能单继承,但是接口支持多继承! * 不能实例化,即不能用 new 来实例化 public interface MyInterface { // 接口中只有:常量,抽象方法 // 定义常量:public static final ...,可省略 String MAX_GREAD = "BOSS"; int MAX_SPEED = 100; // 定义方法:public abstract ...,可省略 void test01(); int test02(int a, int b); } // 接口支持多继承 interface Interface03 extends Interface01, Interface02 ...{ }
7. 多态性
1. 多态性是 OOP 中的一个重要特性,主要是用来实现动态联编的。换句话说,就是程序最终状态只有在执行过程中才能被决定,而不是在编译期间就决定,这对于大型系统来说能提高系统的灵活性和扩展性 2. 多态的存在要有 3 个必要条件: a.要有继承 b.要有方法重写 c.父类引用指向子类对象 public class Fruit { private String color; public void name(){ System.out.println("fruit"); } } public class Apple extends Fruit{ // 继承 @Override public void name(){ // 重写父类方法 System.out.println("apple"); } } public class Test{ public static void main(String[] args) { Fruit f = new Apple(); // 父类引用指向子类对象 f.name(); } }
// 运行结果:apple
8. 内部类
内部类分为静态内部类和动态内部类 * 1.内部类使用的场合:由于内部类提供了更好的封装性,并且可以很方便的访问外部类的属性。所以,通常在只为所在外部类提供服务的情况下优先使用内部类 * 2.内部类被当成其所在外部类的内部属性 * 3.动态内部类可以直接访问外部类的私有属性和方法;静态内部类只能直接访问外部类的静态属性和静态方法,访问非静态成员需要实例化外部类对象 * 4.内部类不允许除了其所在的外部类以外的其他类直接访问 public class TestInnerclass { public static void main(String[] args) { // 其他类访问动态内部类,先实例化外部类对象,再实例化动态内部类 World w = new World(); Human human = w.new Human(); human.hello(); // 其他类访问静态内部类,直接实例化静态内部类对象 Animal animal = new World.Animal(); animal.hello(); } }
public class World{ private String hi = "hello"; public void say(String name){ System.out.println("hello,"+name); } // 动态内部类 class Human{ String name = "man"; void hello(){ //动态内部类直接访问所在外部类的私有属性和方法 System.out.println(hi); say(name); } } // 静态内部类 static class Animal{ String name = "animal"; void hello(){ //静态内部类访问所在外部类的非静态属性和非静态方法必须先实例化外部类对象 World w = new World(); System.out.println(w.hi); w.say(name); } } }
9. 匿名内部类
匿名内部类,一种特殊的内部类,是一个没有显式的名字的内部类 * 1.匿名内部类会隐式的继承一个类或者实现一个接口 * 2.常用于在多线程的实现上,因为要实现多线程必须继承 Thread 类或是实现 Runnable 接口 * 3.匿名内部类只能访问 final 修饰的所在外部类变量及方法参数 * 4.接口本身是不可以通过 new 来实例化的,其实匿名内部类是对接口的实现类的实例化 // Thread 类的匿名内部类 public class Demo { public static void main(String[] args) { Thread t = new Thread() { public void run() { for (int i = 1; i <= 6; i++) { System.out.print(i + " "); } } }; t.start(); } } // Runnable 接口的匿名内部类 public class Demo { public static void main(String[] args) { Runnable r = new Runnable() { public void run() { for (int i = 1; i <= 6; i++) { System.out.print(i + " "); } } }; Thread t = new Thread(r); t.start(); } } //运行结果:1 2 3 4 5 6
10. 异常处理
1. JDK 中定义了很多异常类,所有的异常对象都是派生于 Throwable 类的一个实例,如果内置的异常类不能满足需要,还可以创建自己的异常类 * Throwable * / * Error Exception * / / * Unchecked Exception Checked Exception Runtime Exception * | * Unchecked Exception 2. 使用异常机制建议: * 1.只在异常情况下使用异常机制,避免使用异常处理代替错误处理,这样会降低程序的清晰性,并且效率低 * 2.应该将整个任务包装在一个 try 语句中,不要进行小颗粒的异常处理,即一个 try 语句可以伴随多个 catch,不要一个 catch 一个 try * 3.异常往往在高层处理 3. Checked exception 异常的处理方法之一:捕获异常处理,try{...}catch(Exception e){e.printStackTrace();}finally{...} * “亲自处理” * * 1.try 语句指定代码就是一次捕获并处理的范围 * 2.每个 try 语句可以伴随一个或多个 catch 语句,用于处理可能产生的不同类型异常 * 3.当异常处理的代码执行后,是不会回到 try 语句去执行尚未执行的代码 * * 4.catch 常用的方法: * e.printStackTrace();// 用来跟踪异常事件发生时堆栈的内容 * e.getMessage();// 只显示产生异常的原因,但不显示异常的类名 * e.toString();// 显示异常的原因和异常的类名 * 这些方法均继承自 Throwable 类 * * 5.catch 捕获异常的顺序:如果异常类之间有继承关系,在顺序安排上需注意: * 越是顶层的类,越放在下面,即越是父类,越放下面 * 如:IOException 是 FileNotFoundException 的父类,如果父类在前面是不会去 catch 子类异常 * 再不然就直接把多余的 catch 省掉 * * 6.finally 指定段的语句,不管是否发生异常,都必须执行! * 通常通过 finally 来“关闭程序块已打开的资源”,比如:关闭IO流、释放数据库连接等 * * 7.执行顺序:try,catch,return ——> 执行 finally * 8.由执行顺序可知:不要在 finally 中使用 return 语句,因为会覆盖掉 try 语句中的存在的 return 语句 4. Checked exception 异常的处理方法之二:声明异常,throws
* “谁调我,谁处理” * * 1.当 Checked exception 产生时,不一定要立刻处理它,可以把异常 throws 出去 * 2.当一个方法出现多个 Checked exception,就必须在方法首部列出所有异常,之间用逗号隔开 * * 3.@Override 方法重写时声明异常的规则: * 1.父类方法没有声明异常,子类方法也不能声明异常; * 2.子类方法不可抛出父类方法抛出异常类的父类或更上层类; * 3.子类方法抛出的 异常类型的数目 不可以比父类方法抛出的还多(指不同异常类型个数) 5. Checked exception 异常的处理方法之三:手动抛出异常,throw * 对于一个已经存在的异常类,手动抛出异常对象过程如下: * 1.找到一个合适的异常类 * 2.创建一个该类的对象 * 3.将异常对象抛出 File f = new File("C:/a.txt"); if(!f.exists){ try{ throw new FileNotFoundException("File can't be found!"); }catch(FileNotFoundException e){ e.printStackTrace(); } } 6. 自定义异常处理 * 1.遇到标准异常类都无法充分描述的异常时可以创建自己的异常类 * 2.从 Exception 类或者它的子类派生一个子类即可 * 3.习惯上,定义的异常类应该包含2个构造器: “无参构造器” 和 “带有详细信息的构造器” public class MyException extends Exception{ //无参构造器 public MyException(){ } //带有详细信息的构造器 public MyException(String message){ super(message); } }