Java面向对象1:类、对象、属性(成员变量和局部变量)、方法(方法调用、方法重载、方法重写、构造方法)传值传地址

 开发方法:

结构化开发

● 面向功能划分软件结构

● 自顶向下

● 最小的子系统是方法

● 制约了软件的可维护性和可扩展性

面向对象开发(面向对象程序设计OOP)

● 把软件系统看成各种对象的集合 

● 系统结构较稳定

● 子系统相对独立

● 软件可重用性、可维护性和可扩展性强


1 面向对象

1.1 几个概念(类、对象、属性、方法)

,指的是将所有实体看为对象,实体共同的部分抽象为类。

        即 具有相同属性和方法的一组对象的集合。(共同特征的描述)

关键字class修饰,代表一个自定义类。

对象(具体实例):用来描述客观事物的一个实体,由一组属性和方法构成。

属性:对象具有的各种特征(静态的)。每个对象的每个属性都拥有特定值。

方法(method):对象执行的操作,是程序中最小的执行单元。方法里的代码要么全都执行,要么全都不执行。

重复的代码或具有独立功能的代码可以抽取到方法中,提高代码的复用性可维护性

例:“小狗”这个对象的属性和方法

        属性:颜色(黑色)

        方法:教、跑、吃 

1.2 类和对象的关系

类是对象的抽象,对象是类的具体实现/实例

类 对象名=new 类();    -------创建对象

对象名.属性、对象名.方法()   -----------访问类的内部,类的属性和方法由对象名来调用


2 类 

在Java中,必须先设计类,才能获得对象。

类(设计图):是对象共同特征的描述。

一个.java文件可以定义多个class类,但只能有一个类由public修饰(主类),且主类名与文件名一致。(实际开发中建议还是一个文件定义一个class类。)

2.1 类的定义

public class 类名{  //  类名首字母建议大写,驼峰模式,要见名知意。

        1. 成员变量(代表属性,一般是名词)

        2. 成员方法(代表行为,一般是动词)

        3. 构造器(后面学习)

        4. 代码块(后面学习)

        5. 内部类(后面学习)

}

类名 对象名 = new 类名(); 

 案例:面向对象-02-类和对象_哔哩哔哩_bilibili

定义一个手机类

public class Phone{// 类名是Phone,全限定类名是 包名.Phone
    // 没有main方法,不能运行

    // 属性(成员变量)
    // 一般来说只做声明不做赋值
    String brand;
    double price;
    
    //行为(方法)
    public void call(){
        System.out.println("手机在打电话");
    }
    public void playGame(){
        System.out.println("手机在玩游戏");
    }
}

定义一个测试类 

public class PhoneTest{
    public static void main(String[] args) {
        //创建手机对象
        Phone p = new Phone();

        //给手机赋值
        p.brand = "小米";
        p.price = 1999.98;

        //获取手机对象的值
        System.out.println(p.brand);
        System.out.println(p.price);

        //调用手机中的方法
        p.call();
        p.playGame();

        //第二部手机
        Phone p2 = new Phone();
        p.brand = "苹果";
        p.price = 8999;
    }
}

运行结果: 

2.2 JavaBean类

现在我们所学的类,专业术语叫做 Javabean类,是用来描述一类事物的类。面向对象-06-标准的javabean类_哔哩哔哩_bilibili

javaBean类中是不写main方法的,

之前我们所编写的含有main方法的类,叫做 测试类


3 属性

属性,又叫成员变量、对象变量。

3.1 成员变量

成员变量的完整定义格式:

修饰符 数据类型 变量名称 = 初始化值

一般我们只定义不给值,会有默认值。

类是描述对象的,并不具体,创建对象之后有了特定的对象再给值。

 3.2 局部变量

 局部变量的作用域是该变量被声明的作用域(最贴近的花括号范围)。

 成员变量的作用域是整个类

3.3 成员变量和局部变量的区别

如果成员变量和局部变量同名,则 变量名指向局部变量就近原则

 此时如果要打印成员变量,应该用this.变量名来指向成员变量

 成员变量有对应类型的默认值,而局部变量没有默认值,如果没有初始化,就会编译报错


 4 方法

4.1 方法定义的规则

4.2 方法的分类

方法分为有返回值和无返回值方法:

返回值类型为void,表示该方法没有返回值

  • 主要关注执行过程,可以省略return语句不写;
  • 如果要编写return,后面不能跟具体数据。
    return;//表示结束方法

返回值类型为具体数据类型,表示该方法有返回值

  • 必须有return语句,且return语句返回的值必须能被返回值类型接收,在方法调用处应该有对应的变量接收。
    return 数据; // 表示结束方法和返回结果

 案例(注意成员变量、成员方法的应用):

/**
 * 演示加法运算
 */
public class Add {// 类名是Add ,全限定类名是 包名.Add 
    int x;//属性,又叫成员变量、对象变量
    int y;
    public int sum(){//方法,又叫成员方法、对象方法
        return x+y;//有返回值
    }

    public static void main(String[] args) {
        Add a=new Add();
        a.x=10;
        a.y=20;
        int res=a.sum();//调用sum()方法,返回值赋值给res
        System.out.println(res); // 打印res
    }
}

运行结果:

30

4.3 方法的几个注意项

  • return语句下面不能编写代码,因为return表示结束方法,后面的代码永远不会执行到,属于无效代码。
  • 方法和方法之间是平级关系,不能相互嵌套。
  • 方法的编写顺序和执行顺序无关。
  • 方法不调用就不执行。

4.4 方法调用

方法调用:用对象名.方法名(实参列表);  ------实参列表要和形参列表类型完全对应。

方法之间允许相互调用,不需要知道方法的具体实现,实现重用,提高效率。

调用同一个对象的方法:

public class Function {
    void a(){
        System.out.println("这是a方法");
    }
    void b(){
        a();
        System.out.println("这是b方法");
    }

    public static void main(String[] args) {
        Function f=new Function();
        f.b();
    }
}

 运行结果:

这是a方法
这是b方法

调用不同对象的方法:

public class Function {
    void a(){
        System.out.println("这是a方法");
    }
    void b(){
        a();
        System.out.println("这是b方法");
        Add d=new Add();//成员方法要用对象名字调用
        System.out.println(d.sum());//sum()方法是有返回值的,要么定义一个变量接收返回值,要么直接打印,此为直接打印
    }

    public static void main(String[] args) {
        Function f=new Function();
        f.b();
    }
}

运行结果: 

这是a方法
这是b方法
0

4.5 方法重载

方法重载的规则:

1、在同一类中(从父类继承的也算)

2、方法名相同

3、形参列表不同(参数个数不同、参数顺序不同、参数类型不同)

[4、和访问修饰符、返回值类型无关]

好处:定义方法的时候不用太多的单词,减少调用方法时的麻烦

public class Add{
        public static int sum(int a, int b) {
            return a+b;
        }
        public static int sum(int a,int b,int c){
            return a+b+c;
        }
    }

4.6 方法重写@Override

方法重写的规则:(mv 5.4  08.35.22 - 0:53:20)

1、两个类有继承关系

2、方法名相同

3、参数列表相同

4、访问修饰符的范围必须大于等于父类(public>protected>空着不写)

5、返回值类型必须小于父类

6、抛出的异常范围不嫩比父类更严格(异常范围不能扩大)

7、只有被添加到虚方法表中的方法才能被重写

可以被重写的方法都可以称作虚方法 :不用staticfinalprivate修饰的方法。

public class Test {
    public static void main(String[] args) {
        OverseasStudent s = new OverseasStudent();
        s.lunch();
    }

}
class Person{
    public void eat(){
        System.out.println("吃米饭,吃菜");
    }
    public void drink(){
        System.out.println("喝开水");
    }
}

class OverseasStudent extends Person{
    public void lunch(){
        this.eat();
        this.drink();

        super.eat();
        super.drink();
    }

    @Override
    public void eat() {
        System.out.println("吃意大利面");
    }

    @Override
    public void drink() {
        System.out.println("喝凉水");
    }
}

 运行结果:

吃意大利面
喝凉水
吃米饭,吃菜
喝开水

重写equals()方法的几个关键点

关于 ==和equals的区别:是否比较地址值

==比较的是地址,equals()是基类Object自带的方法,可以重写它也可以不重写:

没有重写equals()方法时,equals()等同于==。此时比较的是地址。

Java.lang.String重写了equals()方法,把equals()的判断变为了判断其值,equals()就不等同于==了。此时比较的是值(内容)。

05-04 08.35.22  2:41:00)

1、用instanceof关键字判断类型是否一致

2、类型一致后,用强制类型转换,将一个object类型转成具体类型

                小类型接收大类型,需要强制类型转换

                大类型接收小类型,会默认转换成大类型

        注意: (非基本类型: 小类型和大类型必须有父子关系)

3、根据业务需要、进行判断

instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。

instanceof 是 Java 的保留关键字。它的作用是测试它左边(引用类型所引用的)对象是否是它右边的类的实例,返回 boolean 的数据类型。

4.7 方法重载和重写的区别

重载是为了实现同一个功能的不同场景

重写是多态的基础,为了解决在不同类型中的同一个功能有不同的表现

4.8 构造方法

构造方法也叫构造器、构造函数。面向对象-05-构造方法_哔哩哔哩_bilibili

每一个类都默认有一个来自Object类的空参构造方法,格式如下:

public 类型名() { }   //方法体为空,功能:创建对象

作用:在创建对象的时候给成员变量进行赋值。

特点:1. 方法名与类名相同,大小写也要一致

           2. 没有返回值类型,连void都没有

           3. 没有具体的返回值,不能由return带回结果数据

执行时机:

构造方法是不能手动调用的,而是在创建对象的时候由虚拟机自动调用;

每创建一次对象,就会调用一次构造方法。

构造方法有无参构造和有参构造:

无参构造:初始化的对象时,成员变量的数据均采用默认值

有参构造:在初始化对象的时候,同时可以为对象进行赋值

一旦我们自定义了有参构造,原来的无参构造系统就不再自动提供,

因此在定义有参构造的同时,应该自主 显式的定义无参构造。

public 类型名(形参列表){

        //代码

}

public 类型名() { } 

一旦自定义有参构造后一定要再手动添加一个无参构造!!!

推荐使用的方式:无论是否使用,都手动书写无参构造方法和带全部参数(父类+子类)的构造方法

​​​​​​​有参构造快捷键:Alt+Insert---constructor    或右键Generate---constructor

 调用的时候:类型名 对象名=new 类型名(实参列表);

​public class Student {
    int stuNo;
    String stuName;
    String gender;
    int age;
    double score;
    public Student(){}//无参构造方法
    public Student(String name,double score){//有参构造方法
        this.name=name;//this代表当前对象,成员变量成员方法都需要用对象名调用,这里的this就代替了对象名
        this.score=score;
    }
}

//调用时
Student stu=new Student("张三",80);

 注意以上代码中的this关键字


5 传值和传地址的区别

5.1 传值

基本数据类型之间传递的是值,改变一个变量的值,不会改变另一个变量的值

int a=1;

int b=a;

b++;//b的值+1,但a的值不会变

----------------------------------

public class A(int num){
    num=num+1;
}

int a=4;
A(a);
System.out.println(a);//此时a的值还是4

5.2 传地址

引用类型的变量传递的是地址(对象的引用),修改一个对象中的属性值,会同步到其他引用中

Student a=new Student();

Student b=a;

b.age=10;//此时a.age也是10

b=new Student();

b.age=18;//此时因为地址改变,不会影响到a.age

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 基础核心总结》 Java 概述 什么是 Java2 Java 的特点Java 开发环境 JDK JRE Java 开发环境配置 Java 基本语法 数据型基础语法运算符 Java 执行控制流程条件语句 if 条件语句 if...else 条件语句if...else if 多分支语句switch 多分支语句 循环语句 while 循环语句do...while 循环for 循环语句 跳转语句 break 语句 continue 语句面向对象 也是-种对象对象的创建 属性方法 构造方法 方法重载 方法的重写 初始化 的初始化 成员初始化 构造器初始化初始化顺序 数组初始化 对象的销毁 对象作用域 this 和 super 访问控制权限继承 多态组合代理 向上转型static final 接口和抽象接口 抽象异常 认 识 Exception 什么是 Throwable 常见的 Exception 与 Exception 有关的 Java 关键字 throws 和 throw try 、finally 、catch 什么是 Error 内部 创建内部集合 Iterable 接口顶层接口 ArrayList Vector LinkedList Stack HashSet TreeSet LinkedHashSet PriorityQueue HashMap TreeMap LinkedHashMap Hashtable IdentityHashMap WeakHashMap Collections 集合实现特征图 泛形 泛型的使用 用泛型表示 用泛型表示接口泛型方法 泛型通配符 反射 Class Field Method ClassLoader 枚举 枚举特性 枚举和普通-样枚举神秘之处 枚举 I/O File 基础 IO 和相关方法InputStream OutputStream Reader Writer InputStream 及其子 OutputStream 及其子Reader 及其子Writer 及其子 注解 关于 null 的几种处理方式大小写敏感 null 是任何引用型的初始值 null 只是-种特殊的值使用 Null-Safe 方法null 判断 关于思维导图 Java.IO Java.lang Java.math Java.net Java 基础核心总结 V2.0 IO 统的 BIO BIO NIO 和 AIO 的区别什么是流 流的分 节点流和处理流 Java IO 的核心 File Java IO 流对象 字节流对象InputStream OutputStream 字符流对象Reader Writer 字节流与字符流的转换新潮的 NIO 缓冲区(Buffer)通道(Channel) 示例:文件拷贝案例 BIO 和 NIO 拷贝文件的区别操作系统的零拷贝 选择器(Selectors) 选择键(SelectionKey) 示例:简易的客户端服务器通信 集合 集合框架总览 -、Iterator Iterable ListIterator 二、Map 和 Collection 接口Map 集合体系详解 HashMap LinkedHashMap TreeMap WeakHashMap Hashtable Collection 集合体系详解 Set 接口 AbstractSet 抽象SortedSet 接口HashSet LinkedHashSet TreeSet List 接口 AbstractList 和 AbstractSequentialList Vector Stack ArrayList LinkedList Queue接口Deque 接口 AbstractQueue 抽象LinkedList ArrayDeque PriorityQueue 反射的思想及作用 反射的基本使用 获取的 Class 对象构造的实例化对象获取-个的所有信息 获取中的变量(Field) 获取中的方法(Method) 获取的构造器(Constructor) 获取注解 通过反射调用方法反射的应用场景 Spring 的 IOC 容器反射 + 抽象工厂模式 JDBC 加载数据库驱动反射的优势及缺陷 增加程序的灵活性破坏的封装性 性能损耗 代理模式 静态代理与动态代理常见的动态代理实现JDK Proxy CGLIB JDK Proxy 和 CGLIB 的对比动态代理的实际应用 Spring AOP 变量 变量汇总实例变量 实例变量的特点全局变量 静态变量 静态变量的特点变量 局部变量
第1章 Java概述 1 1.1 Java语言的发展简史 2 1.2 Java的竞争对手及各自优势 4 1.2.1 C#简介和优势 4 1.2.2 Ruby简介和优势 4 1.2.3 Python的简介和优势 5 1.3 Java程序运行机制 5 1.3.1 高级语言的运行机制 6 1.3.2 Java程序的运行机制和JVM 6 1.4 开发Java的准备 7 1.4.1 安装JDK 8 学生提问:不是说JVM是运行Java程序的虚拟机吗?那JRE和JVM的关系是怎样的呢? 8 学生提问:为什么不安装公共JRE系统呢? 9 1.4.2 设置PATH环境变量 10 学生提问:为什么选择设置用户变量,用户变量和系统变量有什么区别呢? 11 1.5 第一个Java程序 12 1.5.1 编辑Java源代码 12 1.5.2 编译Java程序 13 学生提问:当我们使用编译C程序时,不仅需要指定存放目标文件的位置,也需要指定目标文件的文件名,这里使用javac编译Java程序时怎么不需要指定目标文件的文件名呢? 13 1.5.3 运行Java程序 14 1.5.4 根据CLASSPATH环境变量定位 15 1.6 Java程序的基本规则 16 1.6.1 Java程序的组织形式 16 1.6.2 Java源文件的命名规则 17 1.6.3 初学者容易犯的错误 18 1.7 垃圾回收机制 20 1.8 何时开始使用IDE工具 21 学生提问:老师,我想学习Java编程,到底是学习Eclipse好呢,还是学习JBuilder好呢? 21 1.9 本章小结 22 本章练习 22 第2章 理解面向对象 23 2.1 面向对象 24 2.1.1 结构化程序设计简介 24 2.1.2 程序的三种基本结构 25 2.1.3 面向对象程序设计简介 27 2.1.4 面向对象的基本特征 28 2.2 UML(统一建模语言)介绍 29 2.2.1 用例图 30 2.2.2 图 31 2.2.3 组件图 33 2.2.4 部署图 33 2.2.5 顺序图 34 2.2.6 活动图 34 2.2.7 状态机图 36 2.3 Java面向对象特征 36 2.3.1 一切都是对象 37 2.3.2 对象 37 2.4 本章小结 37 第3章 数据型和运算符 38 3.1 注释 39 3.1.1 单行注释和多行注释 39 3.1.2 文档注释 40 学生提问:API文档是什么? 40 学生提问:为什么要掌握查看API文档的方法? 42 3.2 标识符和关键字 45 3.2.1 分隔符 45 3.2.2 标识符规则 47 3.2.3 Java关键字 47 3.3 数据型分 48 3.4 基本数据型 48 3.4.1 整型 49 3.4.2 字符型 49 3.4.3 浮点型 51 3.4.4 布尔型 52 3.5 基本型的型转换 53 3.5.1 自动型转换 53 3.5.2 强制型转化 54 3.5.3 表达式型的自动提升 56 3.6 直接量 57 3.6.1 直接量的型 57 3.6.2 直接量的赋值 58 3.7 运算符 58 3.7.1 算术运算符 58 3.7.2 赋值运算符 61 3.7.3 位运算符 62 3.7.4 扩展后的赋值运算符 64 3.7.5 比较运算符 65 学生提问:Java为什么要对这些数据进行缓存呢? 67 3.7.6 逻辑运算符 67 3.7.7 三目运算符 68 3.7.8 运算符的结合性和优先级 69 3.8 本章小结 70 本章练习 70 第4章 流程控制和数组 71 4.1 顺序结构 72 4.2 分支结构 72 4.2.1 if条件语句 72 4.2.2 switch分支语句 76 4.3 循环结构 78 4.3.1 while循环语句 78 4.3.2 do while循环语句 79 4.3.3 for循环 80 4.3.4 嵌套循环 83 4.4 控制循环结构 84 4.4.1 使用break结束循环 84 4.4.2 使用continue结束本次循环 86 4.4.3 使用return结束方法 87 4.5 数组型 87 4.5.1 理解数组:数组也是一种型 88 学生提问:int[]是一种型吗?怎么使用这种型呢? 88 4.5.2 定义数组 88 4.5.3 数组的初始化 89 学生提问:能不能只分配内存空间,不赋初始值呢?89 4.5.4 使用数组 90 学生提问:为什么要我记住这些异常信息? 91 4.5.5 JDK1.5提供了foreach循环 91 4.6 深入数组 93 4.6.1 内存中的数组 93 学生提问:为什么有栈内存和堆内存之分? 93 4.6.2 基本型数组的初始化 95 4.6.3 引用型数组的初始化 96 4.6.4 没有多维数组 99 学生提问:我是否可以让图4.13中灰色覆盖的数组元素再次指向另一个数组?这样不可以扩展成三维数组吗?甚至扩展到更多维的数组? 101 4.6.5 操作数组的工具 102 4.6.6 数组的应用举例 103 4.7 本章小结 106 本章练习 106 第5章 面向对象(上) 107 5.1 对象 108 5.1.1 定义 108 学生提问:构造器不是没有返回值吗?为什么不能用void修饰呢? 110 5.1.2 对象的产生和使用 110 5.1.3 对象、引用和指针 111 5.1.4 对象的this引用 112 5.2 方法详解 116 5.2.1 方法的所属性 116 5.2.2 方法的参数递机制 116 5.2.3 形参长度可变的方法 120 5.2.4 递归方法 121 5.2.5 方法重载 123 学生提问:为什么方法的返回值型不能用于区分重载的方法? 124 5.3 成员变量局部变量 124 5.3.1 成员变量局部变量 125 5.3.2 成员变量的初始化和内存中的运行机制 128 5.3.3 局部变量的初始化和内存中的运行机制 130 5.3.4 变量的使用规则 130 5.4 隐藏和封装 132 5.4.1 理解封装 132 5.4.2 使用访问控制符 132 5.4.3 package和import 135 5.4.4 Java的常用包 140 5.5 深入构造器 140 5.5.1 使用构造器执行初始化 141 学生提问:构造器是创建Java对象的途径,是不是说构造器完全负责创建Java对象? 141 5.5.2 构造器的重载 142 学生提问:为什么要用this来调用另一个重载的构造器?我把另一个构造器里的代码复制、粘贴到这个构造器里不就可以了吗? 143 5.6 的继承 144 5.6.1 继承的特点 144 5.6.2 重写父方法 145 5.6.3 父实例的super引用 146 学生提问:我们只是创建了一个Ostrich对象时,哪来的Bird对象? 147 5.6.4 调用构造器 148 学生提问:为什么我创建Java对象时从未感觉到java.lang.Object的构造器被调用过? 150 5.7 多态 151 5.7.1 多态性 151 5.7.2 引用变量的强制型转换 152 5.7.3 instanceof运算符 154 5.8 继承与组合 154 5.8.1 使用继承的注意点 155 5.8.2 利用组合实现复用 156 学生提问:使用组合关系来实现复用时,需要创建两个Animal对象,是不是意味着使用组合关系时系统开销更大? 159 5.9 初始化块 159 5.9.1 使用初始化块 160 5.9.2 初始化块和构造器 161 5.9.3 静态初始化块 162 5.10 本章小结 165 本章练习 165 第6章 面向对象(下) 166 6.1 基本数据型的包装 167 6.2 处理对象 170 6.2.1 打印对象和toString方法 170 6.2.2 ==和equals比较运算符 172 6.3 成员 175 6.3.1 理解成员 175 6.3.2 单例(Singleton) 176 6.4 final修饰符 177 6.4.1 final变量 177 6.4.2 final方法 181 6.4.3 final 182 6.4.4 不可变 182 6.4.5 缓存实例的不可变 186 6.5 抽象 188 6.5.1 抽象方法和抽象 188 6.5.2 抽象的作用 191 6.6 更彻底的抽象:接口 192 6.6.1 接口的概念 192 6.6.2 接口的定义 193 6.6.3 接口的继承 195 6.6.4 使用接口 195 6.6.5 接口和抽象 197 6.6.6 面向接口编程 198 6.7 内部 202 6.7.1 非静态内部 202 学生提问:非静态内部对象和外部对象的关系是怎样的? 206 6.7.2 静态内部 207 学生提问:为什么静态内部实例方法也不能访问外部的实例属性呢? 207 学生提问:接口里是否能定义内部接口? 208 6.7.3 使用内部 208 学生提问:既然内部是外部的成员,是否可以为外部定义子,在子中再定义一个内部来重写其父中的内部? 211 6.7.4 局部内部 211 6.7.5 匿名内部 212 6.7.6 闭包(Closure)和回调 215 6.8 枚举 217 6.8.1 手动实现枚举 217 6.8.2 枚举入门 219 6.8.3 枚举属性方法和构造器 220 6.8.4 实现接口的枚举 223 6.8.5 包含抽象方法的枚举 224 6.9 对象与垃圾回收 225 6.9.1 对象在内存中的状态 226 6.9.2 强制垃圾回收 227 6.9.3 finalize方法 228 6.9.4 对象的软、弱和虚引用 230 6.10 修饰符的适用范围 233 6.11 使用JAR文件 234 6.11.1 jar命令详解 235 6.11.2 创建可执行的JAR包 237 6.11.3 关于JAR包的技巧 238 6.12 本章小结 239 本章练习 239 第7章 Java集合 240 7.1 Java集合概述 241 7.2 Collection和Iterator接口 243 7.2.1 使用Iterator接口遍历集合元素 244 7.2.2 使用foreach循环遍历集合元素 246 7.3 Set接口 247 7.3.1 HashSet 247 学生提问:hashCode方法对于HashSet的作用是什么? 249 7.3.2 TreeSet 252 7.3.3 EnumSet 259 7.4 List接口 261 7.4.1 List接口和ListIterator接口 261 7.4.2 ArrayList和Vector实现 264 7.4.3 固定长度的List 266 7.5 Queue接口 266 7.5.1 LinkedList实现 266 7.5.2 PriorityQueue实现 269 7.6 Map 270 7.6.1 HashMap和Hashtable实现 271 7.6.2 SortedMap接口和TreeMap实现 276 7.6.3 WeakHashMap实现 279 7.6.4 IdentityHashMap实现 280 7.6.5 EnumMap实现 281 7.7 HashSet和HashMap的性能选项 282 7.8 操作集合的工具:Collections 283 7.8.1 排序操作 283 7.8.2 查找,替换操作 287 7.8.3 同步控制 288 7.8.4 设置不可变集合 288 7.9 烦琐的接口:Enumeration 289 7.10 本章小结 290 本章练习 290 第8章 泛型 291 8.1 泛型入门 292 8.1.1 编译时不检查型的异常 292 8.1.2 手动实现编译时检查型 293 8.1.3 使用泛型 294 8.2 深入泛型 294 8.2.1 定义泛型接口、 295 8.2.2 从泛型派生子 296 8.2.3 并不存在泛型 298 8.3 型通配符 298 8.3.1 使用型通配符 300 8.3.2 设定型通配符的上限 300 8.3.3 设定型形参的上限 302 8.4 泛型方法 303 8.4.1 定义泛型方法 303 8.4.2 泛型方法型通配符的区别 306 8.4.3 设定通配符的下限 307 8.4.4 泛型方法方法重载 309 8.5 擦除和转换 310 8.6 泛型与数组 311 8.7 本章小结 313 第9章 与运行环境交互 314 9.1 与用户互动 315 9.1.1 运行Java程序的参数 315 9.1.2 使用Scanner获取键盘输入 316 9.1.3 使用BufferedReader获取键盘输入 318 9.2 系统相关 319 9.2.1 System 319 9.2.2 Runtime 321 9.3 常用 322 9.3.1 Object 322 9.3.2 String、StringBuffer和StringBuilder 322 9.3.3 Math 327 9.3.4 Random 328 9.3.5 BigDecimal 330 9.4 处理日期的 333 9.4.1 Date 333 9.4.2 Calendar 334 9.4.3 TimeZone 337 9.5 正则表达式 338 9.5.1 创建正则表达式 338 9.5.2 使用正则表达式 341 9.6 程序国际化 345 9.6.1 Java国际化的思路 346 9.6.2 Java支持的语言和国家 346 9.6.3 完成程序国际化 347 9.6.4 使用MessageFormat处理包含占位符的字符串 349 9.6.5 使用文件代替资源文件 350 9.6.6 使用NumberFormat格式化数字 350 9.6.7 使用DateFormat格式化日期 352 9.7 本章小结 355 本章练习 355 第10章 异常处理 356 10.1 异常概述 357 10.2 异常处理机制 358 10.2.1 使用try...catch捕获异常 359 10.2.2 异常的继承体系 360 10.2.3 访问异常信息 363 10.2.4 使用finally回收资源 364 10.2.5 异常处理的嵌套 367 10.3 Checked异常和Runtime异常体系 367 10.3.1 使用throws声明抛出异常 367 10.4 使用throw抛出异常 369 10.4.1 抛出异常 369 10.4.2 自定义异常 371 10.4.3 catch和throw同时使用 371 10.4.4 异常链 373 10.5 Java的异常跟踪栈 374 10.6 异常处理规则 376 10.6.1 不要过度使用异常 377 10.6.2 不要使用过于庞大的try块 378 10.6.3 避免使用Catch All语句 378 10.6.4 不要忽略捕获到的异常 379 10.7 本章小结 379 本章练习 379 第11章 AWT编程 380 11.1 GUI(图形用户界面)和AWT 381 11.2 AWT容器 382 11.3 布局管理器 385 11.3.1 FlowLayout布局管理器 386 11.3.2 BorderLayout布局管理器 387 学生提问:BorderLayout最多只能放置5个组件吗?那它还有什么作用? 388 11.3.3 GridLayout布局管理器 389 11.3.4 GridBagLayout布局管理器 390 11.3.5 CardLayout布局管理器 393 11.3.6 绝对定位 395 11.3.7 BoxLayout布局管理器 396 学生提问:图11.15和图11.16显示的所有按钮都紧挨在一起,如果希望像FlowLayout、GridLayout等布局管理器指定组件的间距该怎么办? 397 11.4 AWT 常用组件 398 11.4.1 基本组件 398 11.4.2 对话框 400 11.5 事件处理 403 11.5.1 Java事件模型的流程 403 11.5.2 事件和事件监听器 405 11.5.3 事件适配器 409 11.5.4 事件监听器的实现形式 411 11.6 AWT的菜单 413 11.6.1 菜单条、菜单和菜单项 414 11.6.2 右键菜单 416 学生提问:为什么即使我没有给多行文本域编写右键菜单,但当我在多行文本域上单击右键时一样会弹出右键菜单? 418 11.7 在AWT中绘图 418 11.7.1 画图的实现原理 418 11.7.2 使用Graphics 419 11.8 处理位图 425 11.8.1 Image抽象和BufferedImage实现 425 11.8.2 使用ImageIO输入/输出位图 427 11.9 剪贴板 432 11.9.1 数据递的和接口 432 11.9.2 递文本 433 11.9.3 使用系统剪贴板递图像 435 11.9.4 使用本地剪贴板来对象引用 439 11.9.5 通过系统剪贴板Java对象 442 11.10 本章小结 445 本章练习 445 第12章 Swing编程 446 12.1 Swing概述 447 12.2 Swing基本组件的用法 448 12.2.1 Swing组件层次 448 12.2.2 AWT组件的Swing实现 449 学生提问:为什么单击Swing多行文本域时不是弹出像AWT多行文本域中的右键菜单? 455 12.2.3 使用JToolBar创建工具条 458 12.2.4 使用JColorChooser和JFileChooser 461 12.2.5 使用JOptionPane 469 12.3 Swing中的特殊容器 475 12.3.1 使用JSplitPane 475 12.3.2 使用JTabbedPane 477 12.3.3 使用JLayeredPane、JDesktopPane和JInternalFrame 481 12.4 Swing拖放功能 490 12.4.1 拖放目标 491 12.4.2 拖放源 494 12.4.3 简化的拖放操作 495 12.5 Applet和JApplet 497 12.5.1 Applet简介及其安全性 498 12.5.2 开发Applet 498 12.5.3 使用HTML页面装载Applet 500 12.5.4 appletviewer简介 502 12.5.5 Applet的生命周期和动画机制 503 学生提问:程序中重写paint方法时绘制了一个字符串,但图12.28上则绘制出了如此之多的字符串,这是为什么呢? 505 12.5.6 使用Applet创建音乐播放器 505 12.6 使用JProgressBar、ProgressMonitor和BoundedRangeModel创建进度条 508 12.6.1 创建进度条 508 12.6.2 创建进度对话框 512 12.7 使用JSlider和BoundedRangeModel创建滑动条 513 12.8 使用JSpinner和SpinnerModel创建微调控制器 517 12.9 使用JList、JComboBox创建列表框 520 12.9.1 简单列表框 520 12.9.2 不强制存储列表项的ListModel和ComboBoxModel 524 12.9.3 强制存储列表项的DefaultListModel和DefaultComboBoxModel 528 学生提问:为什么JComboBox提供了添加、删除列表项目的方法?而JList没有提供添加、删除列表项的方法呢? 530 12.9.4 使用ListCellRenderer改变列表项外观 530 12.10 使用JTree和TreeModel创建树 532 12.10.1 创建树 533 12.10.2 拖动、编辑树节点 536 12.10.3 监听节点事件 540 12.10.4 使用TreeCellRendering改变节点外观 542 12.11 使用JTable和TableModel创建表格 549 12.11.1 创建JTable 549 学生提问:我们指定的表格数据、表格列标题都是Object型的数组,JTable如何显示这些Object对象?550 12.11.2 TableModel和监听器 555 12.11.3 TableColumnModel和监听器 561 12.11.4 实现排序 564 12.11.5 绘制单元格内容 567 12.11.6 编辑单元格内容 570 12.12 使用JFormattedTextField和JTextPane创建格式文本 576 12.12.1 监听Document的改变 576 12.12.2 使用JPasswordField 578 12.12.3 使用JFormattedTextField 579 12.12.4 使用JEditorPane 588 12.12.5 使用JTextPane 588 12.13 本章小结 595 本章练习 595 第13章 JDBC编程 596 13.1 JDBC基础 597 13.1.1 JDBC简介 597 13.1.2 JDBC驱动程序型 598 13.2 SQL语法介绍 599 13.2.1 安装数据库 599 13.2.2 关系数据库基本概念和MySQL基本命令 601 13.2.3 SQL语句基础 603 13.2.4 DDL语句 604 13.2.5 DML语句语法 618 13.2.6 select语句和SQL函数 620 13.2.7 分组和组函数 627 13.2.8 多表连接查询和子查询 629 13.3 JDBC的典型用法 635 13.3.1 JDBC常用接口和简介 635 13.3.2 JDBC编程步骤 637 学生提问:前面给出的仅是MySQL和Oracle两种数据库的驱动,我看不出驱动字符串有什么规律啊。如果我希望使用其他数据库,我怎么用其他数据库的驱动呢?637 13.4 执行SQL语句的方式 639 13.4.1 使用executeUpdate执行DDL和DML语句 640 13.4.2 使用execute方法执行SQL语句 642 13.4.3 使用PreparedStatement执行SQL语句 644 13.4.4 使用CallableStatement调用存储过程 650 13.5 管理结果集 652 13.5.1 可滚动、可更新的结果集 652 13.5.2 处理Blob型数据 654 13.5.3 使用ResultSetMetaData分析结果集 660 13.6 事务处理 663 13.6.1 事务的概念和MySQL事务支持 663 13.6.2 JDBC的事务支持 665 13.6.3 批量更新 667 13.7 分析数据库信息 668 13.7.1 使用DatabaseMetaData分析数据库信息 668 13.7.2 使用系统表分析数据库信息 670 13.7.3 选择合适的分析方式 671 13.8 使用连接池管理连接 671 13.9 本章小结 673 本章练习 673 第14章 Annotation(注释) 674 14.1 基本Annotation 675 14.1.1 限定重写父方法:@Override 675 14.1.2 标示已过时:@Deprecated 676 14.1.3 抑制编译器警告:@SuppressWarnings 677 14.2 自定义Annotation 677 14.2.1 定义Annotation 677 14.2.2 提取Annotation的信息 679 14.2.3 使用Annotation的例子 680 14.3 JDK的元Annotation 685 14.3.1 使用@Retention 685 14.3.2 使用@Target 686 14.3.3 使用@Documented 686 14.3.4 使用@Inherited 687 14.4 使用APT处理Annotation 688 14.5 本章小结 693 第15章 输入/输出 694 15.1 File 695 15.1.1 访问文件和目录 695 15.1.2 文件过滤器 697 15.2 理解Java的IO流 698 15.2.1 流的分 698 15.2.2 流的概念模型 699 15.3 字节流和字符流 700 15.3.1 InputStream和Reader 701 15.3.2 OutputStream和Writer 703 15.4 输入/输出流体系 705 15.4.1 处理流的用法 705 15.4.2 输入/输出流体系 706 15.4.3 转换流 708 学生提问:怎么没有把字符流转换成字节流的转换流呢? 708 15.4.4 推回输入流 710 15.5 重定向标准输入/输出 711 15.6 Java虚拟机读写其他进程的数据 713 15.7 RandomAccessFile 716 15.8 对象序列化 720 15.8.1 序列化的含义和意义 720 15.8.2 使用对象流实现序列化 720 15.8.3 对象引用的序列化 723 15.8.4 自定义序列化 728 15.8.5 另一种自定义序列化机制 733 15.8.6 版本 735 15.9 Java新IO 736 15.9.1 Java新IO概述 736 15.9.2 使用Buffer 737 15.9.3 使用Channel 740 15.9.4 编码集和Charset 743 15.9.5 文件锁 745 15.10 本章小结 747 本章练习 747 第16章 多线程 748 16.1 线程概述 749 16.1.1 线程和进程 749 16.1.2 多线程的优势 750 16.2 线程的创建和启动 750 16.2.1 继承Thread创建线程 751 16.2.2 实现Runnable接口创建线程 752 16.2.3 两种方式所创建线程的对比 754 16.3 线程的生命周期 754 16.3.1 新建和就绪状态 754 16.3.2 运行和阻塞状态 756 16.3.3 线程死亡 757 16.4 控制线程 758 16.4.1 join线程 758 16.4.2 后台线程 759 16.4.3 线程睡眠:sleep 760 16.4.4 线程让步:yield 761 16.4.5 改变线程优先级 762 16.5 线程的同步 764 16.5.1 线程安全问题 764 16.5.2 同步代码块 766 16.5.3 同步方法 767 16.5.4 释放同步监视器的锁定 770 16.5.5 同步锁(Lock) 770 16.5.6 死锁 772 16.6 线程通信 774 16.6.1 线程的协调运行 774 16.6.2 使用条件变量控制协调 778 16.6.3 使用管道流 780 16.7 线程组和未处理的异常 782 16.8 Callable和Future 785 16.9 线程池 787 16.10 线程相关 789 16.10.1 ThreadLocal 789 16.10.2 包装线程不安全的集合 791 16.10.3 线程安全的集合 792 16.11 本章小结 792 第17章 网络编程 793 17.1 网络编程的基础知识 794 17.1.1 网络基础知识 794 17.1.2 IP地址和端口号 795 17.2 Java的基本网络支持 796 17.2.1 使用InetAddress 796 17.2.2 使用URLDecoder和URLEncoder 797 17.2.3 使用URL和URLConnection 798 17.3 基于TCP协议的网络编程 806 17.3.1 TCP协议基础 806 17.3.2 使用ServletSocket创建TCP服务器端 807 17.3.3 使用Socket进行通信 807 17.3.4 加入多线程 810 17.3.5 记录用户信息 813 17.3.6 使用NIO实现非阻塞Socket通信 823 17.4 基于UDP协议的网络编程 829 17.4.1 UDP协议基础 829 17.4.2 使用DatagramSocket发送、接收数据 829 17.4.3 使用MulticastSocket实现多点广播 834 17.5 使用代理服务器 845 17.5.1 直接使用Proxy创建连接 845 17.5.2 使用ProxySelector选择代理服务器 847 17.6 本章小结 849 本章练习 849 第18章 加载和反射 850 18.1 的加载、连接和初始化 851 18.1.1 JVM和 851 18.1.2 的加载 852 18.1.3 的连接 853 18.1.4 的初始化 853 18.1.5 初始化的时机 854 18.2 加载器 855 18.2.1 加载器简介 856 18.2.2 加载机制 857 18.2.3 创建并使用自定义的加载器 858 18.2.4 URLClassLoader 862 18.3 通过反射查看信息 863 18.3.1 获得Class对象 863 18.3.2 从Class中获取信息 864 18.4 使用反射生成并操作对象 868 18.4.1 创建对象 868 18.4.2 调用方法 870 18.4.3 访问属性值 873 18.4.4 操作数组 874 18.5 使用反射生成JDK动态代理 875 18.5.1 使用Proxy和InvocationHandler创建动态代理 876 18.5.2 动态代理和AOP 878 18.6 反射和泛型 882 18.6.1 泛型和Class 882 18.6.2 使用反射来获取泛型信息 884 18.7 本章小结 885 本章练习 886
基本数据型的包装 •八大数据型的包装分别为:Byte、Short、Integer、Long、Character、 Float、Double、Boolean。 把基本数据型变量包装实例是通过对应包装的构造器来实现的,不仅如此,8个包装中除了 Character之外,还可以通过入一个字符串参数来构建包装对象。 •如果希望获得包装对象中包装的基本型变量,则可以使用包装提供的XxxValue()实例方法。 自动装箱与自动拆箱 •JDk还提供了自动装箱和自动拆箱。自动装箱就是把一个基本型的变量直接赋给对应的包装变量,自动拆箱 则与之相反。 •包装还可以实现基本型变量和字符串之间的转换,除了Character之外的所有包装都提供了一个 parseXxx(String s)静态方法。 •如果将基本型转换为这符串,只需在后面加+ “”进行连接运算。 Java 7对包装的增强 •Java 7为所有包装增加一个新方法: compare(x , y)的方法。该方法用于比较两个包装实例,当x>y, 返回大于0的数;当x==y,返回0;否则返回小于0的数。 对象方法 •打印对象和toString方法:toString方法是系统将会输出该对象的“自我描述”信息,用以告诉外界对象具有的状 态信息。 •Object 提供的toString方法总是返回该对象实现名 + @ +hashCode值。 •==和equals比较运算符:==要求两个引用变量指向同一个对象才会返回true。equals方法则允许用户提供自 定义的相等规则。 •Object提供的equals方法判断两个对象相等的标准与==完全相同。因此开发者通常需要重写equals方法成员 •在java里只能包含Field,方法,构造器,初始化块,内部(接口、枚举)等5种成员。 用static修饰的成员属 于成员,Field既可通过来访问,也可以通过对象来访问。当通过对象来访问属性时,系统会在底 层转换为通过该来访问 属性成员规则 •成员并不是属于实例,它是属于本身的。只要存在,成员就存在。 •即使通过null对象来访问成员,程序也不会引发NullPointerException。   成员不能访问实例成员。 单例 •如果一个始终只能创建一个对象,称为单例。须符合以下几个条件:   –1.我们把该的构造器使用Private修饰,从而把该 的所有构造器隐藏起来。   –2.则需要提供一个public方法作为该的访问点,用于创建该对象,且必须使用static修饰   –3.该还必须缓存已经创建的对象,必须用static修饰 final变量 •final修饰变量时,表示该变量一旦获得 初始值之后就不可被改变。 •final既可修饰成员变量,也可以修饰局部变量。 final修饰成员变量成员变量是随的初始化或对象初始化而初始化的。final修饰的成员变量必须由程序员指定初始值。 •对于属性而言,要么在静态初始化中初始化,要么在声明该属性时初始化。 •对于实例属性,要么在普通初始化块中指定初始值。要么在定义时、或构造器中指定初始值。 final修饰局部变量 •使用final修饰局部变量时既可以在定义时指定默认值,也可以不指定默认值。 •给局部变量赋初始值,只能一次,不能重复。 final修饰基本型和引用型 •当使用final修饰基本数据型时,不能对其重新赋值,不能被改变。 •但对引用型的变量而言,它仅仅保存的是一个引用,final只能保证他的地址不变,但不能保证对象,所以引用 型完全可以改变他的对象。 可执行“宏替换”的final变量 •对一个final变量来说,不管它是变量、实例变量,还是局部变量,只要该变量满足3个条件,这个final变量就 不再是一个变量,而是相当于一个直接量。   –使用final修饰符修饰;   –在定义该final变量时指定了初始值;   –该初始值可以在编译时就被确定下来。 final方法 •final方法 •final 修饰的方法不可以被重写。 •final 修饰的方法仅仅是不能重写,但它完全可以被重载。 •final 修饰的不可以被继承 不可变的 •不可变的要满足以下几个条件:   –1.使用private和final修饰符来修饰该属性   –2.提供带参数的构造器,用于根据入参数来初始化里的属性   –3.仅为该属性提供getter方法,不要为该属性提供setter方法,因为普通方法无法修改final修饰的 属性   –4.如有必要,重写Object中hashCode 和equals •缓存实例的不可变:如果程序经常需要使用不可变的实例,则可对实例进行缓存。 抽象方法和抽象 •抽象方法都必须使用abstract来修饰,有抽象方法只能定义成抽象,抽象里也可以没有抽象方法。 • 抽象不能被实例化,可以通过其子给他赋值,普通里有的抽象里也有,定义抽象方法只需在普通方法上增 加abstract修饰符,并把普通方法方法体(也就是方法后花括号括起来的部分)全部去掉,并在方法后增加分号 即可。 抽象的特征 •抽象的特征:有得有失,得到了新能力,可以拥有抽象方法;失去了创建对象的能力。 抽象的作用 •抽象代表了一种未完成的设计,它体现的是一种模板。 •抽象与模板模式。 接口的概念 •接口定义的是多个共同的行为规范,这些行为是与外部交流的通道,这就意味着接口里通常是定义一组公用的 方法。 •接口体现了规范与实现分离的设计。 接口的定义 •和定义不同,定义接口不再用class关键字,而是使用interface关键字。语法如下: •[修饰符] interface接口名 extends 父接口1,父接口2 ... •{ • 零个到多个常量定义... • 零个到多个抽象方法定义... • 零个到多个内部、接口、枚举定义... • 零个到多个默认方法方法定义... •} 接口里的成分 •在定义接口时,接口里可以包含成员变量(只能是常量),方法(只能是抽象实例方法方法或默认方法),内 部(包括内部接口、枚举   –常量都是:public static final修饰   –方法都是:public abstract 修饰   –内部的:public static 接口的继承 •接口的继承和继承不一样,接口完全支持多继承,子接口扩展某个父接口将会获得父接口的所有抽象方法,常 量属性,内部和枚举定义。 使用接口 •接口可以用于声明引用型的变量,但接口不能用于创建实例。 •当使用接口来声明引用型的变量时,这个引用型的变量必须引用到其实现对象。 •一个可以实现一个或多个接口,继承使用extends关键字,实现接口则使用implements关键字。 实现接口 •一个实现了一个或多个接口之后,这个必须完全实现这些接口里所定义的全部抽象方法(也就是重写这些抽 象方法); •否则,该将保留从父接口那里继承到的抽象方法,该也必须定义成抽象。 接口和抽象的相似性 •接口和抽象都不能被实例化,它们都位于继承树的顶端,用于被其他实现和继承。 •接口和抽象都可以包含抽象方法,实现接口或继承抽象的普通子都必须实现这些抽象方法。 接口与抽象的区别 •接口里只能包含抽象方法,不同包含已经提供实现的方法;抽象则完全可以包含普通方法。 •接口里不能定义静态方法;抽象里可以定义静态方法。 •接口里只能定义静态常量属性,不能定义普通属性;抽象里则既可以定义普通属性,也可以定义静态常量属 性。 •接口不包含构造器;抽象里可以包含构造器,抽象里的构造器并不是用于创建对象,而让其子调用这些构 造器来完成属于抽象的初始化操作。 •接口里不能包含初始化块,但抽象则完全可以包含初始化块。 •一个最多只能有一个直接父,包括抽象;但一个可以直接实现多个接口,通过实现多个接口可以弥补 Java单继承的不足。 面向接口编程 •接口体现了规范与实现分离的原则。充分利用接口可以很好地提高系统的可扩展性和可维护性。 •接口与简单工厂模式、命令模式等。 内部 •我们把一个放在另一个的内部定义,这个定义在其他内部的就被称为内部,有的也叫嵌套,包含内   部也被称为外部有的也叫宿住。 •内部提供了更好的封装,内部成员可以直接访问外部的私有数据,因为内部被当成其他外部成员。 •匿名内部适合用于创建那些仅需要一次使用的。 非静态内部 •定义内部非常简单,只要把一个放在另一个内部定义即可。 •当在非静态内部方法内访问某个变量时,系统优先在该方法内查找是否存在该名字的局部变量,如果存在该 名字的局部变量,就使用该变量,如果不存在,则到该方法所在的内部中查找是否存在该名字的属性,如果存在 则使用该属性。 •总之,第一步先找局部变量,第二步,内部属性,第三步。外部属性。 本文原创作者:pipi-changing 本文原创出处:http://www.cnblogs.com/pipi-changing/ 静态内部 •如果用static修饰一个内部,称为静态内部。 •静态内部可以包含静态成员,也可以包含非静态成员。所以静态内部不能访问外部的实例成员,只能访问   外部成员。 •静态内部对象寄存在外部里,非静态内部对象寄存在外部实例里 使用内部 •1.在外部内部使用内部-不要在外部的静态成员中使用非静态内部,因为静态成员不能访问非静态成 员。 • 2.在外部以外使用非静态内部。   –private 修饰的内部只能在外部内部使用。   –在外部以外的地方使用内部,内部完整的名应该OuterClass.InnerClass.   –在外部以外的地方使用非静态内部创建对象的语法如下:OuterInstance.new InnerConstructor()   –在外部以外的地方使用静态内部创建对象的语法如下:new OuterClass.InnerConstructer(); 局部内部 •如果把一个内部放在方法里定义,这就是局部内部,仅仅在这个方法里有效。 •局部内部不能在外部以外的地方使用,那么局部内部也不能使用访问控制符和static修饰 匿名内部 •匿名内部适合创建那种只需要一次使用的,定义匿名内部的语法格式如下: •new 父构造器(实例列表) |实现接口) •{ • //匿名内部体部分 •} •匿名内部不能是抽象,匿名内部不能定义构造器。 Lambda表达式入门 •Lambda表达式主要作用就是代替匿名内部的繁琐语法。它由三部分组成:   –形参列表。形参列表允许省略形参型。如果形参列表中只有一个参数,甚至连形参列表的圆括号也可以省略。   –箭头(->),必须通过英文等号和大于符号组成。   –代码块。如果代码块只有包含一条语句,Lambda表达式允许省略代码块的花括号,如果省略了代码块的花括 号,这条语句不要用花括号表示语句结束。Lambda代码块只有一条return语句,甚至可以省略return关键字。 Lambda表达式需要返回值,而它的代码块中仅有一条省略了return的语句,Lambda表达式会自动返回这条语句的 值。 Lambda表达式与函数式接口 •如果采用匿名内部语法来创建函数式接口的实例,只要实现一个抽象方法即可,在这种情况下即可采用 Lambda表达式来创建对象,该表达式创建出来的对象的目标型就是这个函数式接口。 •Lambda表达式有如下两个限制:   –Lambda表达式的目标型必须是明确的函数式接口。   –Lambda表达式只能为函数式接口创建对象。Lambda表达式只能实现一个方法,因此它只能为只有一个抽 象方法的接口(函数式接口)创建对象。 •为了保证Lambda表达式的目标型是一个明确的函数式接口,可以有如下三种常见方式:   –将Lambda表达式赋值给函数式接口型的变量。   –将Lambda表达式作为函数式接口型的参数给某个方法。   –使用函数式接口对Lambda表达式进行强制型转换。 方法引用与构造器引用 种 示例 说明 对应的Lambda表达式 引用方法 名::方法 函数式接口中被实现方法的全部参数给该方法作为参数。 (a,b,...) -> 名.方法(a,b, ...) 引用特定对象的实例方法 特定对象::实例方法 函数式接口中被实现方法的全部参数给该方法作为参数。 (a,b, ...) -> 特定对象.实例方法(a,b, ...) 引用某对象的实例方法 名::实例方法 函数式接口中被实现方法的第一个参数作为调用者,后面的参数全部给该方法作为参数。 (a,b, ...) ->a.实例方法(b, ...) 引用构造器 名::new 函数式接口中被实现方法的全部参数给该构造器作为参数。 (a,b, ...) ->new 名(a,b, ...) Lambda表达式与匿名内部 •Lambda表达式与匿名内部存在如下相同点:   –Lambda表达式与匿名内部一样,都可以直接访问“effectively final”的局部变量,以及外部的成员变 量(包括实例变量和变量)。   –Lambda表达式创建的对象与匿名内部生成的对象一样, 都可以直接调用从接口继承得到的默认方法。 •Lambda表达式与匿名内部主要存在如下区别:   –匿名内部可以为任意接口创建实例——不管接口包含多少个抽象方法,只要匿名内部实现所有的抽象方 法即可。但Lambda表达式只能为函数式接口创建实例。   –匿名内部可以为抽象、甚至普通创建实例,但Lambda表达式只能为函数式接口创建实例。   –匿名内部实现的抽象方法方法体允许调用接口中定义的默认方法;但Lambda表达式的代码块不允许调 用接口中定义的默认方法。 手动实现枚举 •可以采用如下设计方式:   –通过private将构造器隐藏起来。   –把这个的所有可能实例都使用public static final属性来保存。   –如果有必要,可以提供一些静态方法,允许其他程序根据特定参数来获取与之匹配实例。 JDK 5新增的枚举支持 •J2SE1.5新增了一个enum关键字,用以定义枚举。正如前面看到,枚举是一种特殊的,它一样可以有自 己的方法属性,可以实现一个或者多个接口,也可以定义自己的构造器。一个Java源文件中最多只能定义一个 public访问权限的枚举,且该Java源文件也必须和该枚举名相同。 枚举 •枚举可以实现一个或多个接口,使用enum定义的枚举默认继承了java.lang.Enum,而不是继承Object 。其中java.lang.Enum实现了java.lang.Serializable和java.lang. Comparable两个接口。 •枚举的构造器只能使用private访问控制符,如果省略了其构造器的访问控制符,则默认使用private修饰;如 果强制指定访问控制符,则只能指定private修饰符。 •枚举的所有实例必须在枚举中显式列出,否则这个枚举将永远都不能产生实例。列出这些实例时系统会自 动添加public static final修饰,无需程序员显式添加。 •所有枚举都提供了一个values方法,该方法可以很方便地遍历所有的枚举值。 枚举属性方法和构造器 •枚举也是一种,只是它是一种比较特殊的,因此它一样可以使用属性方法。 •枚举通常应该设计成不可变,也就说它的属性值不应该允许改变,这样会更安全,而且代码更加简洁。为 此,我们应该将枚举属性都使用private final 修饰。 •一旦为枚举显式定义了带参数的构造器,则列出枚举值时也必须对应地入参数。 实现接口的枚举 •枚举也可以实现一个或多个接口。与普通实现一个或多个接口完全一样,枚举实现一个或多个接口时,也 需要实现该接口所包含的方法。 •如果需要每个枚举值在调用同一个方法时呈现出不同的行为方式,则可以让每个枚举值分别来实现该方法,每个 枚举值提供不同的实现方式,从而让不同枚举值调用同一个方法时具有不同的行为方式。 包含抽象方法的枚举 •可以在枚举里定义一个抽象方法,然后把这个抽象方法交给各枚举值去实现即可。 •枚举里定义抽象方法时无需显式使用abstract关键字将枚举定义成抽象,但因为枚举需要显式创建枚举 值,而不是作为父,所以定义每个枚举值时必须为抽象方法提供实现,否则将出现编译错误。 垃圾回收机制 •垃圾回收机制只负责回收堆内存中对象,不会回收任何任何物理资源(例如数据库连接,网络IO等资源)。 •程序无法精确控制垃圾回收的运行,垃圾回收会在合适时候进行垃圾回收。当对象永久性地失去引用后,系统就 会在合适时候回收它所占的内存。 •垃圾回收机制回收任何对象之前,总会先调用它的finalize方法,该方法可能使该对象重新复活(让一个引用变量 重新引用该对象),从而导致垃圾回收机制取消回收 对象在内存中的状态 •激活状态:当一个对象被创建后,有一个以上的引用变量引用它。则这个对象在程序中处于激活状态,程序可通 过引用变量来调用对象属性方法。 •去活状态:如果程序中某个对象不再有任何引用变量引用它,它就进入了去活状态。在这个状态下,系统的垃圾 回收机制准备回收该对象所占用的内存,在回收该对象之前,系统会调用所有去活状态对象的finalize方法进行资 源清理,如果系统在调用finalize方法重新让一个引用变量引用该对象,则这个对象会再次变为激活状态;否则该 对象将进入死亡状态。 •死亡状态:当对象与所有引用变量的关联都被切断,且系统会调用所有对象的finalize方法依然没有使该对象变成 激活状态,那这个对象将永久性地失去引用,最后变成死亡状态。只有当一个对象处于死亡状态时,系统才会真正 回收该对象所占有的资源。 强制垃圾回收 •强制系统垃圾回收有如下两个方法:   –调用System的gc()静态方法:System.gc()   –调用Runtime对象的gc()实例方法:Runtime.getRuntime().gc() finalize方法 •finalize方法有如下四个特点:   –永远不要主动调用某个对象的finalize方法,该方法应交给垃圾回收机制调用。   –finalize方法的何时被调用,是否被调用具有不确定性。不要把finalize方法当成一定会被执行的方法。   –当JVM执行去活对象的finalize方法时,可能使该对象,或系统中其他对象重新变成激活状态。   –当JVM执行finalize方法时出现了异常,垃圾回收机制不会报告异常,程序继续执行。 对象的软、弱和虚引用 •强引用(StrongReference) •软引用-软引用需要通过SoftReference来实现,当一个对象只具有软引用时,它有可能被垃圾回收机制回 收。 •弱引用-弱引用通过WeakReference实现,弱引用和软引用很像,但弱引用的引用级别更低。对于只有弱引 用的对象而言,当系统垃圾回收机制运行时,不管系统内存是否足够,总会回收该对象所占用的内存。 •虚引用-虚引用通过PhantomReference实现,虚应用完全似于没有引用。虚引用对对象本身没有太大影 响,对象甚至感觉不到虚引用的存在。 修饰符的适用范围 顶层/接口 成员属性 方法 构造器 初始化块 成员内部 局部成员 public √ √ √ √ √ protected √ √ √ √ 包访问控制符 √ √ √ √ ○ √ ○ private √ √ √ √ abstract √ √ √ final √ √ √ √ √ static √ √ √ √ strictfp √ √ √ synchronized √ native √ transient √ volatile √ 使用JAR文件的好处 •1.安全 •2.加快下载速度 •3.压缩 •4.包封装 •5.可移植性 jar命令详解 •-c 创建新文档,-t 列出存档内容的列表, -x 展开存档中的命名文件 •-u 更新已存在的存档,-v生成详细输出到标准输出上 •-f 指定存档文件名,-m 包含 来自标文件的标明信息 •-o 只存储方式:未用ZIP压缩格式 •-m 不产生所有项的清单文件,- I 为指定的jar文件产生索引信息 •-c 改变到指定的目录, 创建可执行的JAR包 •1.使用平台相关的编译器将整个应用编译成平台相关的可执行性文件 •2.为整个应用编辑一个批处理文件 关于JAR包的技巧 •相当于一个压缩文件。 •可使用WinRAR来压缩JAR包。 •也可使用WinRAR来查看JAR包。 现在贴出代码: AutoBoxingUnboxing Primitive2String UnsignedTest WrapperClassCompare EqualTest Person OverrideEqualsRight PrintObject StringCompareTest ToStringTest NullAccessStatic Singleton Address CacheImmutaleTest FinalErrorTest FinalLocalTest FinalLocalVariableTest FinalMethodTest FinalReferenceTest FinalReplaceTest FinalVariableTest ImmutableStringTest IntegerCacheTest Person Sub extends PrivateFinalMethodTest StringJoinTest CarSpeedMeter Circle extends Shape abstract class Shape SpeedMeter Triangle 复制代码 public class AddCommand implements Command { public void process(int[] target) { int sum = 0; for (int tmp : target) { sum += tmp; } System.out.println("数组元素的总和是:" + sum); } } **************************************************** public class BetterPrinter implements Output { private String[] printData = new String[MAX_CACHE_LINE * 2]; // 用以记录当前需打印的作业数 private int dataNum = 0; public void out() { // 只要还有作业,继续打印 while (dataNum > 0) { System.out.println("高速打印机正在打印:" + printData[0]); // 把作业队列整体前移一位,并将剩下的作业数减1 System.arraycopy(printData, 1, printData, 0, --dataNum); } } public void getData(String msg) { if (dataNum >= MAX_CACHE_LINE * 2) { System.out.println("输出队列已满,添加失败"); } else { // 把打印数据添加到队列里,已保存数据的数量加1。 printData[dataNum++] = msg; } } } ************************************************ public interface Command { // 接口里定义的process()方法用于封装“处理行为” void process(int[] target); } ********************************************** public class CommandTest { public static void main(String[] args) { ProcessArray pa = new ProcessArray(); int[] target = { 3, -4, 6, 4 }; // 第一次处理数组,具体处理行为取决于PrintCommand pa.process(target, new PrintCommand()); System.out.println("------------------"); // 第二次处理数组,具体处理行为取决于AddCommand pa.process(target, new AddCommand()); } } ************************************************* public class Computer { private Output out; public Computer(Output out) { this.out = out; } // 定义一个模拟获取字符串输入的方法 public void keyIn(String msg) { out.getData(msg); } // 定义一个模拟打印的方法 public void print() { out.out(); } } ********************************************** interface interfaceA { int PROP_A = 5; void testA(); } interface interfaceB { int PROP_B = 6; void testB(); } interface interfaceC extends interfaceA, interfaceB { int PROP_C = 7; void testC(); } public class InterfaceExtendsTest { public static void main(String[] args) { System.out.println(interfaceC.PROP_A); System.out.println(interfaceC.PROP_B); System.out.println(interfaceC.PROP_C); } } ************************************************** public interface Output { // 接口里定义的成员变量只能是常量 int MAX_CACHE_LINE = 50; // 接口里定义的普通方法只能是public的抽象方法 void out(); void getData(String msg); // 在接口中定义默认方法,需要使用default修饰 default void print(String... msgs) { for (String msg : msgs) { System.out.println(msg); } } // 在接口中定义默认方法,需要使用default修饰 default void test() { System.out.println("默认的test()方法"); } // 在接口中定义方法,需要使用static修饰 static String staticTest() { return "接口里的方法"; } } ********************************************** public class OutputFactory { public Output getOutput() { // return new Printer(); return new BetterPrinter(); } public static void main(String[] args) { OutputFactory of = new OutputFactory(); Computer c = new Computer(of.getOutput()); c.keyIn("轻量级Java EE企业应用实战"); c.keyIn("疯狂Java讲义"); c.print(); } } *********************************************** public class OutputFieldTest { public static void main(String[] args) { // 访问另一个包中的Output接口的MAX_CACHE_LINE System.out.println(lee.Output.MAX_CACHE_LINE); // 下面语句将引起"为final变量赋值"的编译异常 // lee.Output.MAX_CACHE_LINE = 20; // 使用接口来调用方法 System.out.println(lee.Output.staticTest()); } } ************************************************ public class PrintCommand implements Command { public void process(int[] target) { for (int tmp : target) { System.out.println("迭代输出目标数组的元素:" + tmp); } } } *********************************************** // 定义一个Product接口 interface Product { int getProduceTime(); } // 让Printer实现Output和Product接口 public class Printer implements Output, Product { private String[] printData = new String[MAX_CACHE_LINE]; // 用以记录当前需打印的作业数 private int dataNum = 0; public void out() { // 只要还有作业,继续打印 while (dataNum > 0) { System.out.println("打印机打印:" + printData[0]); // 把作业队列整体前移一位,并将剩下的作业数减1 System.arraycopy(printData, 1, printData, 0, --dataNum); } } public void getData(String msg) { if (dataNum >= MAX_CACHE_LINE) { System.out.println("输出队列已满,添加失败"); } else { // 把打印数据添加到队列里,已保存数据的数量加1。 printData[dataNum++] = msg; } } public int getProduceTime() { return 45; } public static void main(String[] args) { // 创建一个Printer对象,当成Output使用 Output o = new Printer(); o.getData("轻量级Java EE企业应用实战"); o.getData("疯狂Java讲义"); o.out(); o.getData("疯狂Android讲义"); o.getData("疯狂Ajax讲义"); o.out(); // 调用Output接口中定义的默认方法 o.print("孙悟空", "猪八戒", "白骨精"); o.test(); // 创建一个Printer对象,当成Product使用 Product p = new Printer(); System.out.println(p.getProduceTime()); // 所有接口型的引用变量都可直接赋给Object型的变量 Object obj = p; } } ************************************************* public class ProcessArray { public void process(int[] target, Command cmd) { cmd.process(target); } } 复制代码 。。。。。。。。。。。。。。。。
定义 •定义的语法格式: •[修饰符] class 名 {….体…..} •体可以由多个属性方法、构造器组成。 •注意:的修饰符可以是public、final 或省略这两个。名只要是合法的标识符. •一个里可以包含三种最常见的成员:构造器、属性方法。 定义属性的格式语法 •[修饰符] 属性属性名 [= 默认值]; 定义方法的格式语法 •[修饰符] 方法返回值方法名(形参列表) {….方法体….} – 方法中的修饰符可以是public ,protected,private,static,final,abstract,其中访问控制符只能出现一 个,abstract ,final 只能出现其一. –返回值型可以是基本型和引用型,如果无返回值,要用void 来声明 –形参列表,可以由零到多组组成,参数之间用逗号(“,”)隔开. –static 是一个特殊的关键字,译为”静态”,所有有static 修饰的叫属性,方法,成员. 定义构造器的语法格式 •[修饰符] 构造器名(形参列表) {……} –修饰符可以是public protected private 构造器必须和名相同,形参和方法的形参一样. 对象的产生和使用 •创建对象的根本途径就是构造器,所以创建对象通过关键字new 加上对应的构造器即可. •如果访问权限允许,里定义的属性方法可以通过或实例来调用, •有static 修饰的访求和属性,既可通过调用,也可以通过实例来调用. 对象.引用和指针 •Person p = new Person();,这行代码创建了一个Person 实例,也被称为对象,这个对象被赋给了p变量. •也就是说引用型变量里存放的仅仅是一个引用,它指向实际的对象. 对象的this 引用 •this 关键字总是指向调用方法对象.   –1.构造器中引用该构造器执行初始化的对象   –2.在方法中引用调用方法对象 •在方法里的this 指谁调用就指谁 •注: this 不能用在有static 修饰的方法中. 方法的详解 •方法的所属性   –一旦将一个方法定义在一个里,如果用static 修饰了,这个方法属于这个,否则属于这个对象.   –方法不能独立执行,必须要有调用者.(如:.方法对象.方法)   –方法不能独立定义,只能定义在里.   –方法要么属于一个,要么属于一个对象 方法的参数递机制 递方式只有一种:值递. 形参长度可变的方法 •如果在定义方法时,在最后一个参数的型后增加三点…,则表明该形参接受多个参数值,多个参数值被当成数组   入. •长度可变的形参只能位于最后一个参数,并一个方法里只能有一个可变长度的参数. 递归 •递归就是在方法中再次调用自己。 •递归一定要向已知方向递归. 方法的重载 •Java 允许在一个里定义多个同名方法,只要形参列表不同即可. •所以方法的重载只要满足两个条件(两同一不同):1.同一个中,方法名相同;2.形参不同。和返回值型无关.   所以在调用这些方法时要入不同的参数值. 成员变量局部变量成员变量指的是在范围里定义的变量;局部变量指的是在一个方法内定义的变量。 •不管是成员变量还是局部变量都遵守相同的命名规则。 •成员变量分为属性和实例属性.对于属性无论通过还是对象来访问都是访问同一个对象,只要一个对象改变 了属性,那么其他对象对应的属性也改变了.成员变量不用显式初始化,只要定义了一个属性或实例属性,系统 默认进行初始化。 局部变量局部变量可分为三种:   –形参   –方法局部变量   –代码块局部变量. •与成员变量不同的是除了形参外,其他局部变量都必须显式地初始化, •Java 里允许局部变量成员变量重名。这样局部变量会覆盖成员变量,这时通过this 来调用实例的属性. 成员变量的初始化 •当被加载时,成员就在内存中分配了一块空间。 •当对象被创建时,实例成员就在内存中分配了内存空间。 •实例变量与实例共存亡;变量与本身共存亡。 局部变量的运行机制 •局部变量仅在方法内有效。 •当方法执行完成时,局部变量便会自动销毁。 封装 •理解封装:封装是面向对象的三大特征之一。 • 封装包含两方面含义:   –合理隐藏。   –合理暴露。 本文原创作者:pipi-changing 本文原创出处:http://www.cnblogs.com/pipi-changing/ 使用访问控制符 •private 私有的。在同一个里能被访问。 •default 默认的。包访问权限 •protected 受保护的。子中也能访问 •public 公共的。在任何地方都可以访问 package 和 import •package 打包格式:package 包名;放在程序开始的顶端。 •包机制的两个方面的保证。1.源文件里要使用package 语句指定包。2.class 文件必须放在对应的路径下。 •import 引入包格式。分为两种:   –非静态导入,导入的是包下所有的。如:import package.subpackage.*;   –静态导入,导入的是的静态属性。如:import static package.className.*; Java 的常用包 •java.lang.*, •java.util.*, •java.net.* , •java.io.*, •java.text.*, •java.sql.*, •java.awt.*, •java.swing.*. 使用构造器执行初始化 •构造器最大的用处就是在创建对象时执行初始化,系统会默认的进行初始化。 •如果程序员没有Java 提供任何构造器,则系统会为这个提供一个无参的构造器。 •一旦程序员提供了自定义的构造器,遇系统不再提供默认的构造器。 构造器的重载 •构造器的重载和方法的重载一样,都是方法名相同,形参列表不相同。 •在构造器中可通过this来调用另外一个重载的构造器。 继承的特点 •Java通过关键字extends来实现,实现继承的称为子,被继承的称为基、超、父。父是大,子   是小。 •Java的继承是单继承,每个子最多只有一个直接父。 本文原创作者:pipi-changing 本文原创出处:http://www.cnblogs.com/pipi-changing/ 继承 •子继承父的语法格式如下: •修饰符 class subclass extends superclass {。。。。。。} •子扩展了父,将可以获得父的全部属性方法,但不能获得父构造器 •Java里的继承都是单继承,也就是只能有一个直接的父,可以有n个间接父。 重写父方法方法的重写要遵循“两同两小一大” 指的是:方法名相同,形参列表相同。返回值型更小或相同,抛出的异常更   小或相同,访问控制权限要更大。 父实例的super限定 •通过关键字super 来调用方法属性。 super调用的构造器 •子构造器总会调用构造器。 •如果子构造器没有显式使用super调用构造器;子构造器默认会调用无参数的构造器。 •创建一个子实例时,总会先调用最顶层父的构造器。 多态性 •Java 引用变量有两个型:一个是编译时的型,一个是运行时的型,编译时的型由声明该变量时使用的   型决定,运行时的型由实际赋给该变量的对象决定。 •如果编译时型和支行时的型不一致,这就有可能出现所谓的多态。 •两个相同型的引用变量,由于它们实际引用的对象型不同,当它们调用同名方式时,可能呈现出多种行为   特征,这就是多态。 引用变量的型转换 •将一个子对像赋给父,这就是向上转型。向上转型是自动的。 •强制型转换: 型转换运算符是小括号,语法如下(type)variable; instanceof运算符 •前一个操作通常是一个引用型的变量,后一个操作通常是一个(也可以是接   口)。如果是 返回true, 否返回false。 继承和组合 •使用继承的注意点 •利用组合实现复用:总之,继承要表达的是一种“是(is-a)”的关系,而组合表达的是”有(has-a)“的关系。 本文原创作者:pipi-changing 本文原创出处:http://www.cnblogs.com/pipi-changing/ 初始化块 •使用初始化块:初始化块由大括号括起{…},只能由static修饰。 •初始化块和构造器:初始化块总在构造器之前执行,初始化块不能接受形参。 静态初始化块 •用static修饰的初始化块为静态初始化块,由于是静态的,所以是属于,当加载时,就执行静态初始化块 ,   但执行一个子时,最先执行其最顶层父的静态初始化, •初始化块是属于实例 的。只要创建一次对象,初始化块就执行一次。 下面贴出代码: Dog DogTest Person PersonTest ReturnThis StaticAccessNonStatic ThisInConstructor Overload OverloadVarargs PrimitiveTransferTest Recursive ReferenceTransferTest Varargs 复制代码 public class BlockTest { public static void main(String[] args) { { // 定义一个代码块局部变量a int a; // 下面代码将出现错误,因为a变量还未初始化 // System.out.println("代码块局部变量a的值:" + a); // 为a变量赋初始值,也就是进行初始化 a = 5; System.out.println("代码块局部变量a的值:" + a); } // 下面试图访问的a变量并不存在 // System.out.println(a); } // 代码块局部变量a的值:5 } 复制代码 。。。。。。。。。。。。。。。。。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值