只要删繁、捋清脉络,才能掌握本质!只有创新才有价值,保持创新、保持学习!
计划:UNIAPP+SPRINGBOOT学习、SPRINGBOOT+VUE新版学习、页面展示学习、PYTHON。
*******************************************************************************************************************************************
第一章:Java 程序设计概述
*******************************************************************************************************************************************
1、关键术语:
1 ) 简单性:里没有头文件、 指针运算(甚至指针语法)、结构、 联合、 操作符重载、 虚基类等。
2 ) 面向对象: 一个“ 面向对象的” 木匠始终关注的是所制作的椅子, 第二位才是所使用的工具;一个“ 非面向对象的” 木匠首先考虑的是所用的工具。
3 ) 分布式:Java 有一个丰富的例程库,用于处理像 HTTP 和 FTP 之类的 TCP/IP 协议。Java 应用程序能够通过 URL 打开和访问网络上的对象,其便捷程度就好像
访问本地文件一样。
4 ) 健壮性:Java 编译器能够检测许多在其他语言中仅在运行时才能够检测出来的问题。
5 ) 安全性:使用 Java 可以构建防病毒、 防篡改的系统。
6 ) 体系结构中立:精心设计的字节码不仅可以很容易地在任何机器上解释执行,而且还可以动态地翻译成本地机器代码。
7 ) 可移植性:与 C 和 C++ 不同,Java 规范中没有“ 依赖具体实现” 的地方基本教据类型的大小以及有关运算都做了明确的说明。你可以处理文件、 正则表达式、 XML、 日期和时间、 数据库、 网络连接、 线程等,而不用操心底层操作系统。不仅程序是可移植的,Java API 往往也比原生 API 质量更高。
8 ) 解释型:Java 解释器可以在任何移植了解释器的机器上执行 Java 字节码。
9 ) 高性能:字节码可以(在运行时刻)动态地翻译成对应运行这个应用的特定 CPU 的机器码。
10 ) 多线程:Java 在当时很超前。它是第一个支持并发程序设计的主流语言。确保用户界面不会“ 冻住”。
11 ) 动态性:当需要将某些代码添加到正在运行的程序中时, 动态性将是一个非常重要的特性。一个很好的例子是: 从 Internet 下载代码,然后在浏览器上运行。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2、applet 与 Internet
1)用户从 Internet 下载 Java 字节码, 并在自己的机器上运行。在网页中运行的 Java 程序称为 applet。要使用 applet, 需要启用 Java 的 Web 浏览器执行字节码。不需要安装任何软件。任何时候只要访问包含 applet 的网页都会得到程序的最新版本。后来,Java 遭遇了严重的安全问题,浏览器和 Java 浏览器插件变得限制越来越多。如今,要在浏览器中使用 applet, 这不仅需要一定的水平, 而且要付出努力。例如,如果访问 Jmol 网站,可能会看到一个消息, 警告你要适当地配置浏览器允许运行applet。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
3、Java发展简史
1)Java 的历史要追溯到 1991 年,由 Patrick Naughton 和 James Gosling (一个全能的计算机奇才)带领的 Sun 公司的工程师小组想要设计一种小型的计算机语言。
2)1996 年年初,Sun 发布了 Java 的第 1 个版本:
3)2014 年 ,Java 8终于发布,在近 20 年中这个版本有了最大的改变。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
4、Java 的常见误解
1)Java 是 HTML 的扩展、使用 XML, 所以不需要 Java、Java 是一种非常容易学习的程序设计语言、JavaScript 是 Java 的简易版...
*******************************************************************************************************************************************
第二章:Java 程序设计环境
*******************************************************************************************************************************************
1、安 装 Java 幵发工具包
1)为 Linux 、 Mac OS X、Solaris 和 Windows 提供了 Java 开发工具包( JDK ) 的最新、 最完整的版本。
2)安装配置 java javac
*******************************************************************************************************************************************
第三章:Java 的基本程序设计结构 52页
*******************************************************************************************************************************************
1、一个简单的 Java 应用程序
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2、注 释
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
3、数 据 类 型
1)Java 有一个能够表示任意精度的算术包, 通常称为“ 大数值”( bignumber )。虽然 被称为大数值,但它并不是一种新的 Java 类型,而是一个 Java 对象。 本章稍后将会详细 地介绍它的用法。
2)整型:用于表示没有小数部分的数值, 它允许是负数。在通常情况下,int 类型最常用。但如果表示星球上的居住人数, 就需要使用 long 类型 了。byte 和 short 类型主要用于特定的应用场合,例如,底层的文件处理或者需要控制占用 存储空间量的大数组。
3)浮点型:double 表示这种类型的数值精度是 float 类型的两倍(有人称之为双精度数值)。绝大部 分应用程序都采用 double 类型。在很多情况下,float 类型的精度很难满足需求。
4)char 类型:char 类型原本用于表示单个字符。不过,现在情况已经有所变化。 如今,有些 Unicode 字符可以用一个 char值描述,另外一些 Unicode 字符则需要两个 char 值。
5)Unicode 和 char 类型:我们强烈建议不要在程序中使用 char 类型,除非确实需要处理 UTF-16 代码单元。最好 将字符串作为抽象数据类型处理。
6)布尔类型:boolean (布尔)类型有两个值:false 和 true, 用来判定逻辑条件 整型值和布尔值之间 不能进行相互转换。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
4、变量
1)在 Java 中,每个变量都有一个类型( type)。在声明变量时,变量的类型位于变量名之前。
2)变量名必须是一个以字母开头并由字母或数字构成的序列。
3)声明一个变量之后,必须用赋值语句对变量进行显式初始化, 千万不要使用未初始化的变量。
4)常量:在 Java 中, 利用关键字 final 指示常量。关键字 final 表示这个变量只能被赋值一次。一旦被赋值之后,就不能够再更改了。习惯上, 常量名使用全大写。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
5、运 算 符
1)在 Java 中,使用算术运算符 + 、-、 * 、/ 表示加、减、 乘、除运算。 当参与 / 运算的两个 操作数都是整数时, 表示整数除法;否则, 表示浮点除法。 整数的求余操作(有时称为取模) 用 % 表示。
2)在 Math类中,包含了各种各样的数学函数。在编写不同类别的程序时,可能需要的函 数也不同。 要想计算一个数值的平方根, 可以使用 sqrt 方法。
3)数值类型之间的转换:经常需要将一种数值类型转换为另一种数值类型。
4)在必要的时候, int 类型的值将会自动地转换为 double 类型。但另 一方面,有时也需要将 double 转换成 int。 在 Java 中, 允许进行这种数值之间的类型转换。 当然, 有可能会丢失一些信息。在这种情况下,需要通过强制类型转换( cast) 实现这个操 作。
5)关系和 boolean 运算符
6)括号与预算符级别
7)枚举的使用
package day;
public class AIMain {
public static void main(String[] args) {
Color color = Color.GREEN;
System.out.println(color); // 打印出来就是GREEN 值
}
enum Color {
RED, GREEN, BLANK, YELLOW
}
}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
6、字 符 串
1)String 类的 substring 方法可以从一个较大的字符串提取出一个子串
2)与绝大多数的程序设计语言一样,Java语言允许使用 + 号连接(拼接)两个字符串。
3)可以使用 equals 方法检测两个字符串是否相等。对于表达式: s.equals(t)
4)空串 "" 是长度为 0 的字符串。String 变量还可以存 放一个特殊的值, 名为 null, 这表示目前没有任何对象与该变量关联
5)Java 中的 String类包含了 50 多个方法。令人惊讶的是绝大多数都很有用, 可以设想使 用的频繁非常高。下面的 API 注释汇总了一部分最常用的方法。
•boolean startsWith(String prefix ) •boolean endsWith(String suffix ) 如果字符串以 suffix 开头或结尾, 则返回 true。 •int indexOf(String str)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
7、输入输出
1)前面已经看到,打印输出到“ 标准输出流”(即控制台窗口)是一件非常容易的事情,只要 调用 System.out.println 即可。然而,读取“ 标准输人流” System.in 就没有那么简单了。要想通 过控制台进行输人,首先需要构造一个 Scanner 对象,并与“ 标准输人流” System.in 关联。
2)示例
public class AIMain {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入你的名字:");
String name = scanner.nextLine();
System.out.println("你的名字是:" + name);
}
}
3)Scanner读取文件内容
public class AIMain {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(Paths.get("src/main/resources/files/1.txt"), "UTF-8");
while (scanner.hasNext()) {
String res = scanner.nextLine();
System.out.println(res);
}
}
}
4)输出内容到文件中
public class AIMain {
public static void main(String[] args) throws IOException {
PrintWriter printWriter = new PrintWriter("src/main/resources/files/out.txt", "UTF-8");
printWriter.println("输出信息");
printWriter.flush();
printWriter.close();
}
}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
8、控制流程80页
1)switch
public class AIMain {
public static void main(String[] args) throws IOException {
int a = 0;
switch (a) {
case 0:
System.out.println("a=0");
break;
case 1:
System.out.println("a=1");
break;
}
a = 1;
switch (a) {
case 0:
System.out.println("a=0");
break;
case 1:
System.out.println("a=1");
break;
}
}
}
2)if else
3)循环 while for
4)中断控制流程语句 条件满足 break;
与 C++ 不同,Java 还提供了一种带标签的 break语句,用于跳出多重嵌套的循环语句。 有时候,在嵌套很深的循环语句中会发生一些不可预料的事情。此时可能更加希望跳到嵌套 的所有循环语句之外。通过添加一些额外的条件判断实现各层循环的检测很不方便。 这里有一个示例说明了 break 语句的工作状态。请注意,标签必须放在希望跳出的最外 层循环之前, 并且必须紧跟一个冒号。
public class AIMain {
public static void main(String[] args) throws IOException {
break_tag:
while (true) {
for (int i = 0; i < 10000; i++) {
System.out.println(i);
while (i < 50) {
int k = 0;
for (int j = 0; j < 100; j++) {
System.out.println("我打印的:" + j);
if (k > 3 && j > 90) {
break break_tag;
}
k++;
}
}
}
}
}
}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
9、大数值
1)如果基本的整数和浮点数精度不能够满足需求, 那么可以使用jaVa.math 包中的两个 很有用的类:Biglnteger 和 BigDecimaL 这两个类可以处理包含任意长度数字序列的数值。 Biglnteger 类实现了任意精度的整数运算, BigDecimal 实现了任意精度的浮点数运算。
10、数组
1)数组是一种数据结构, 用来存储同一类型值的集合。通过一个整型下标可以访问数组中 的每一个值。例如, 如果 a 是一个整型数组, a[i] 就是数组中下标为 i 的整数。
2)for each 循环语句显得更加简洁、 更不易出错(不必为下标的起始值和终止值而操心)。
public class AIMain {
public static void main(String[] args) throws IOException {
String[] myArray = new String[3];
myArray[0] = "0";
myArray[1] = "1";
myArray[2] = "1";
for (String temp : myArray) {
System.out.println(temp);
}
}
}
3)数组初始化以及匿名数组
4)前面已经看到多个使用 Java 数组的示例。 每一个 Java 应用程序都有一个带 String arg[] 。 参数的 main 方法。这个参数表明 main 方法将接收一个字符串数组,也就是命令行参数。
5)要想对数值型数组进行排序, 可以使用 Arrays 类中的 sort 方法。
6)多维数组将使用多个下标访问数组元素, 它适用于表示表格或更加复杂的排列形式。
*******************************************************************************************************************************************
第四章:对象与类
*******************************************************************************************************************************************
1、面向对象程序设计概述
1)类( class) 是构造对象的模板或蓝图。我们可以将类想象成制作小甜饼的切割机,将对象想象为小甜饼。由类构造(construct) 对象的过程称为创建类的实例 (instance )。
2)实现封装的关键在于绝对不能让类中的方法直接地访问其他类的实例域。程序仅通过对 象的方法与对象数据进行交互。封装给对象赋予了“ 黑盒” 特征, 这是提高重用性和可靠性 的关键。 这意味着一个类可以全面地改变存储数据的方式,只要仍旧使用同样的方法操作数据, 其他对象就不会知道或介意所发生的变化。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2、对象
首先从设计类开始,然后再往每个类中添加方法。
这些名词很可能成为类 Item、 Order 等。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
3、在类之间, 最常见的关系有 •依赖(“ uses-a”) •聚合(“ has-a”) •继承(“ is-a”)应该尽可能地将相互依赖的类减至最少。
预定义类:在 Java 中, 没有类就无法做任何事情, 我们前面曾经接触过几个类。然而,并不是所有 的类都具有面向对象特征。例如,Math 类。在程序中,可以使用 Math 类的方法, 如 Math, random, 并只需要知道方法名和参数(如果有的话),而不必了解它的具体实现过程。这正是 封装的关键所在,当然所有类都是这样。但遗憾的是,Math 类只封装了功能,它不需要也不 必隐藏数据。由于没有数据,因此也不必担心生成对象以及初始化实例域。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
4、静态域与静态方法
1)静态域 nextld 也存在。它属于类,而不属于任何独立的对象。
2)静态变量使用得比较少,但静态常量却使用得比较多。例如, 在 Math 类中定义了一个静态常量。
3)静态方法是一种不能向对象实施操作的方法。例如, Math 的 pow 方法就是一静态方法。表达式 Math.pow(x, a)。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
5、方法参数
1)Java 程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
6、对象构造
1)重载、new对象、构造函数、无参构造器、有参构造器。
2)Java 还有第三种机制, 称为初始化块(initializationblock)。在一个类的声明中, 可以包含多个代码块。只要构造类的对象,这些块就会被执行。
在这个示例中,无论使用哪个构造器构造对象,id 域都在对象初始化块中被初始化。首 先运行初始化块,然后才运行构造器的主体部分。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
7、包
1)Java 允许使用包( package > 将类组织起来。借助于包可以方便地组织自己的代码,并将 自己的代码与别人提供的代码库分开管理。
2)更简单且更常用的方式是使用 import 语句。import 语句是一种引用包含 在包中的类的简明描述。一旦使用了 import 语句,在使用类时,就不必写出包的全名了。
3)import 语句不仅可以导入类,还增加了导人静态方法和静态域的功能。
4)要想将一个类放人包中, 就必须将包的名字放在源文件的开头,包中定义类的代码之 前。例如,程序清单 4-7中的文件 Employee.java 开头是这样的: package com.horstiann.corejava;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
8、类 路 径
1)C:\classdir;.;C:\archi»es\archive.jar
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
9、文档注释
JDK 包含一个很有用的工具,叫做javadoc, 它可以由源文件生成一个 HTML 文档。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
10、类设计技巧
1)一定要保证数据私有
2)一定要对数据初始化
3)不要在类中使用过多的基本类型
4)不是所有的域都需要独立的域访问器和域更改器
5)将职责过多的类进行分解
6)类名和方法名要能够体现它们的职责
7)优先使用不可变的类
*******************************************************************************************************************************************
第五章:继承
*******************************************************************************************************************************************
1、类、超类和子类
1)假设你在某个公司工作,这 个公司中经理的待遇与普通雇员的待遇存在着一些差异。不过, 他们之间也存在着很多相同 的地方,例如, 他们都领取薪水。只是普通雇员在完成本职任务之后仅领取薪水, 而经理在 完成了预期的业绩之后还能得到奖金。这种情形就需要使用继承。(我不这么认为,这么做会增加类之间依赖和复杂度)。2)抽象类
如果自下而上在类的继承层次结构中上移,位于上层的类更具有通用性,甚至可能更加抽象。从某种角度看, 祖先类更加通用, 人们只将它作为派生其他类的基类,而不作为想使用的特定的实例类。例如, 考虑一下对 Employee 类层次的扩展。一名雇员是一个人, 一名学生也是一个人。下面将类 Person 和类 Student 添加到类的层次结构中。图 5-2 是这三个类 之间的关系层次图。 为什么要花费精力进行这样高层次的抽象呢? 每个人都有一些诸如姓名这样的属性。学生与雇员都有姓名属性, 因此可以将 getName 方法放置在位于继承关系较高层次的通用超类中。
3)Object: 所有类的超类 190页
Object 类是 Java 中所有类的始祖, 在 Java 中每个类都是由它扩展而来的。但是并不需要这样写: public class Employee extends Object
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
3、泛型数组列表
1)ArrayList 是一个采用类型参数( type parameter ) 的泛型类( generic class)。为了指定数 组列表保存的元素对象类型,需要用一对尖括号将类名括起来加在后面, 例如,ArrayList <Employee> 。在第 8 章中将可以看到如何自定义一个泛型类, 这里并不需要了解任何技术细 节就可以使用 ArrayList 类型。
这被称为“ 菱形” 语法,因为空尖括号 o就像是一个菱形。可以结合 new 操作符使用菱形 语法。编译器会检查新值是什么。如果赋值给一个变量,或传递到某个方法,或者从某个方 法返回,编译器会检査这个变量、 参数或方法的泛型类型,然后将这个类型放在o中。在 这个例子中,new ArrayListo()将赋至一个类型为 ArrayList<Employee> 的变量, 所以泛型 类型为 Employee。
2)集合的遍历
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
4、对象包装器与自动装箱
1)ArrayList<Integer> list = new ArrayList<>();
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
5、参数数量可变的方法
用的不多,反而增加了不确定性。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
6、枚举类
package day;
public class AIMain {
public static void main(String[] args) {
Color color = Color.GREEN;
System.out.println(color); // 打印出来就是GREEN 值
}
enum Color {
RED, GREEN, BLANK, YELLOW
}
}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
7、反射
1)能够分析类能力的程序称为反射(reflective )。反射机制的功能极其强大,在下面可以看 到, 反射机制可以用来: •在运行时分析类的能力。 •在运行时查看对象, 例如, 编写一个 toString 方法供所有类使用。 实现通用的数组操作代码。 利用 Method 对象, 这个对象很像中的函数指针。 反射是一种功能强大且复杂的机制。 使用它的主要人员是工具构造者,而不是应用程序员如果仅对设计应用程序感兴趣, 而对构造工具不感兴趣, 可以跳过本章的剩余部分, 稍后再返回来学习。
2)在程序运行期间,Java 运行时系统始终为所有的对象维护一个被称为运行时的类型标识。 这个信息跟踪着每个对象所属的类。 虚拟机利用运行时类型信息选择相应的方法执行。 然而, 可以通过专门的 Java 类访问这些信息。保存这些信息的类被称为 Class, 这 个 名 字很容易让人混淆。Object 类中的 getClass( ) 方法将会返回一个 Class 类型的实例。
public class AIMain {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.getClass());
}
}
3)捕获异常
如果没有提供处理器,程序就会终止,并在控制台上打印出一条信息, 其中给出了异常的 类型。可能在前面已经看到过一些异常报告, 例如, 偶然使用了 null 引用或者数组越界等。
4)利用反射分析类的能力
import day.pojo.Person;
public class AIMain {
public static void main(String[] args) throws Exception {
Person person = new Person();
person.setSex("女");
System.out.println(person.getClass());
System.out.println(person.getClass().getName());
System.out.println(person.getClass().getField("sex"));
String sex = (String) person.getClass().getField("sex").get(person);
System.out.println(sex);
System.out.println(person.getClass().getConstructor());
System.out.println(person.getClass().getMethod("getName"));
}
}
5)事实上, Java 的设计者曾说过:方法指针是很危险的,并且常常会带来隐患。他们认为 Java 提供的 接口(interface ) (将在下一章讨论)是一种更好的解决方案。然而, 反射机制允许你调用任意 方法。
6)继承的设计技巧
除非所有继承的方法都有意义,否则不要使用继承。
*******************************************************************************************************************************************
第6章 接口、lambda 表达式与内部类
*******************************************************************************************************************************************
1、在 Java 程序设计语言中, 接口不是类,而是对类的一组需求描述,这些类要遵从接口描 述的统一格式进行定义。 我们经常听到服务提供商这样说:“ 如果类遵从某个特定接口,那么就履行这项服务 ' 下面给出一个具体的示例。Arrays 类中的 sort 方法承诺可以对对象数组进行排序,但要求满足下列前提:对象所属的类必须实现了 Comparable 接口。
1)这就是说,任何实现 Comparable 接口的类都需要包含 compareTo 方法,并且这个方法的参数必须是一个 Object 对象,返回一个整型数值。
public class Person implements Comparable<Person> { // 排序谁泛型谁
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Person other) {
return this.age - other.age; // 这里用了this与other比较
}
}
public class AIMain {
public static void main(String[] args) throws Exception {
Person person1 = new Person();
person1.setAge(30);
Person person2 = new Person();
person2.setAge(10);
Person person3 = new Person();
person3.setAge(20);
List<Person> personList = new ArrayList<>();
personList.add(person1);
personList.add(person2);
personList.add(person3);
Collections.sort(personList); // 这里关键调用了比较方法
for (Person temp : personList) {
System.out.println(temp.getAge());
}
}
}
2)接口与抽象类
非常遗憾, 使用抽象类表示通用属性存在这样一个问题: 每个类只能扩展于一个类。假 设 Employee 类已经扩展于一个类, 例如 Person, 它就不能再像下面这样扩展第二个类了。
而接口可以多实现。
3)静态方法
在 Java SE 8 中,允许在接口中增加静态方法。理论上讲,没有任何理由认为这是不合法 的。只是这有违于将接口作为抽象规范的初衷。
4)默认方法
可以为接口方法提供一个默认实现。 必须用 default 修饰符标记这样一个方法。
当然, 这并没有太大用处, 因为 Comparable 的每一个实际实现都要覆盖这个方法。不过 有些情况下, 默认方法可能很有用。 例如,在第 11 章会看到, 如果希望在发生鼠标点击事 件时得到通知,就要实现一个包含 5 个方法的接口。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2、接口示例
1)回调
回调( callback) 是一种常见的程序设计模式。在这种模式中,可以指出某个特定事件发生时应该采取的动作。例如,可以指出在按下鼠标或选择某个菜单项时应该采取什么行动。 然而,由于至此还没有介绍如何实现用户接口,所以只能讨论一些与上述操作类似,但比较 简单的情况。
在 java.swing 包中有一个 Timer 类,可以使用它在到达给定的时间间隔时发出通告。 例 如,假如程序中有一个时钟,就可以请求每秒钟获得一个通告, 以便更新时钟的表盘。
2)Comparator 接口
要按长度比较字符串,可以如下定义一个实现 Comparator<String> 的类。
3)对象克隆
本节我们会讨论 Cloneable 接口,这个接口指示一个类提供了一个安全的 clone 方法。由 于克隆并不太常见,而且有关的细节技术性很强,你可能只是想稍做了解,等真正需要时再 深人学习。
要不要在自己的类中实现 clone 呢? 如果你的客户需要建立深拷贝,可能就需要实现这 个方法。有些人认为应该完全避免使用 clone, 而实现另一个方法来达到同样的目的。clone 相当笨拙, 这一点我们也同意,不过如果让另一个方法来完成这个工作, 还是会遇到同样的 问题。毕竟, 克隆没有你想象中那么常用。标准库中只有不到 5% 的类实现了clone。
4)lambda 表达式
现在可以来学习 lambda 表达式, 这是这些年来 Java 语言最让人激动的一个变化。你会 了解如何使用 lambda 表达式采用一种简洁的语法定义代码块, 以及如何编写处理 lambda 表达式的代码。
lambda 表达式是一个可传递的代码块, 可以在以后执行一次或多次。
到目前为止,在 Java 中传递一个代码段并不容易, 不能直接传递代码一段 Java 是一种面 向对象语言,所以必须构造一个对象,这个对象的类需要有一个方法能包含所需的代码。
5)函 数 式 接 口(虽然好,但是不常用)
Arrays.sort (words, (first, second) -> first.length - second.length);
lambda 表达式可以转换为接口, 这一点让 lambda 表达式很有吸引力。
ArrayList 类有一个 removelf 方法, 它的参数就是一个 Predicate。这个接口专门用来传递 lambda 表达式。例如,下面的语句将从一个数组列表删除所有 null 值: list.removelf(e -> e == null);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
3、内部类
1)内部类( inner class) 是定义在另一个类中的类。为什么需要使用内部类呢? 有以下三点: •内部类方法可以访问该类定义所在的作用域中的数据, 包括私有的数据。 •内部类可以对同一个包中的其他类隐藏起来。 •当想要定义一个回调函数且不想编写大量代码时,使用匿名 (anonymous) 内部类比较便捷。
2)当在 Java 1.1 的 Java语言中增加内部类时,很多程序员都认为这是一项很主要的新特性, 但这却违背了 Java 要比 C++ 更加简单的设计理念。内部类的语法很复杂(可以看到,稍后介 绍的匿名内部类更加复杂 )。它与访问控制和安全性等其他的语言特性的没有明显的关联。 由于增加了一些看似优美有趣, 实属没必要的特性,似乎 Java 也开始走上了许多语言饱 受折磨的毁灭性道路上。 我们并不打算就这个问题给予一个完整的答案。 内部类是一种编译器现象, 与虚拟机无 关。编译器将会把内部类翻译成用 $ (美元符号)分隔外部类名与内部类名的常规类文件, 而 虚拟机则对此一无所知。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
4、代理
1)利用代理可以在运行时创建一个实现了一组给 定接1J 的新类 : 这种功能只有在编译时无法确定需要实现哪个接 U 时才冇必要使用。用程序设计人员来说, 遇到这种情况的机会很少。如果对这种高级技术不感兴趣,可以跳过 本节内容。然而,对于系统程序设计人员来说,代理带来的灵活性却十分重要。
*******************************************************************************************************************************************
第7章 异常、断言和曰志
*******************************************************************************************************************************************
1、处理错误
1)假设在一个 Java 程序运行期间出现了一个错误。这个错误可能是由于文件包含了错误 信息,或者网络连接出现问题造成的,也有可能是因为使用无效的数组下标, 或者试图使用 一个没有被赋值的对象引用而造成的。用户期望在出现错误时, 程序能够采用一些理智的行 为。如果由于出现错误而使得某些操作没有完成, 程序应该: •返回到一种安全状态,并能够让用户执行一些其他的命令;或者 •允许用户保存所有操作的结果,并以妥善的方式终止程序。
在 Java 程序设计语言中, 异常对象都是派生于 Throwable 类的一个实例。稍后还可以看到,如果 Java 中内置的异常类不能够满足需求,用户可以创建自己的异常类。需要注意的是,所有的异常都是由 Throwable 继承而来,但在下一层立即分解为两个分支:Error 和 Exception:
2)声明受查异常
如果遇到了无法处理的情况, 那么 Java 的方法可以抛出一个异常。这个道理很简单:一 个方法不仅需要告诉编译器将要返回什么值,还要告诉编译器有可能发生什么错误。例如, 一段读取文件的代码知道有可能读取的文件不存在, 或者内容为空,因此, 试图处理文件信 息的代码就需要通知编译器可能会抛出 IOException 类的异常。
3)如何抛出异常
首先要决定应该抛出什么类型的异常。将上述异常归结为 IOException 是一种很好的选 择。仔细地阅读 Java API 文档之后会发现:EOFException 异常描述的是“ 在输人过程中, 遇 到了一个未预期的 EOF 后的信号”。
4)创建异常类
class MyException extends Exception{}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2、捕获异常
1)要想捕获一个异常, 必须设置 try/catch语句块。
2)捕获多个异常:在一个 try 语句块中可以捕获多个异常类型,并对不同类型的异常做出不同的处理。可 以按照下列方式为每个异常类型使用一个单独的 catch 子句。3)finally 子句。Java 有一种更好的解决方案,这就是 finally 子句。下面将介绍 Java 中如何恰当地关闭 一个文件。如果使用 Java 编写数据库程序,就需要使用同样的技术关闭与数据库的连接。在 卷 n 的第 4 章中可以看到更加详细的介绍。当发生异常时,恰当地关闭所有数据库的连接是 非常重要的。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
3、使用异常机制的技巧
1)异常处理不能代替简单的测试
2)不要过分地细化异常
3)利用异常层次结构
4)不要压制异常
5)在检测错误时,“ 苛刻 ” 要比放任更好
6)不要羞于传递异常
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
4、使用断言
1)断言的概念
2)启用和禁用断言
3)使用断言完成参数检查
4)为文档假设使用断言
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
5、记录日志【321】
1)每个 Java 程序员都很熟悉在有问题的代码中插入一些 System.out.println 方法调用来帮助观察程序运行的操作过程。
2)基本曰志
3)高级曰志
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
6、调试技巧
1)假设编写了一个程序, 并对所有的异常进行了捕获和恰当的处理,然后,运行这个程序,但 还是出现问题,现在该怎么办呢(如果从来没有遇到过这种情况, 可以跳过本章的剩余部分)? 当然,如果有一个方便且功能强大的调试器就太好了。
2)可以用下面的方法打印或记录任意变量的值: System.out.println( "x=" + x);
3)一个不太为人所知但却非常有效的技巧是在每一个类中放置一个单独的 main方法。 这样就可以对每一个类进行单元测试。
4)如果喜欢使用前面所讲述的技巧,就应该到 http://junit.org 网站上査看一下 JUnit。 JUiiit 是一个非常常见的单元测试框架,利用它可以很容易地组织测试用例套件。只要修改 类,就需要运行测试。在发现 bug 时,还要补充一些其他的测试用例
5)日志代理( logging proxy) 是一个子类的对象, 它可以截获方法调用, 并进行日志记 录,然后调用超类中的方法。例如,如果在调用 Random 类的 nextDouble 方法时出现了问 题, 就可以按照下面的方式,以匿名子类实例的形式创建一个代理对象。
6)利 用 Throwable 类提供的 printStackTmce 方法,可以从任何一个异常对象中获得堆栈 情况。. 下面的代码将捕获任何异常,打印异常对象和堆栈轨迹, 然后,重新拋出异常, 以便 能够找到相应的处理器。
7)通常, 将一个程序中的错误信息保存在一个文件中是非常有用的。然而,错误信息 被发送到 System.err 中,而不是 System.out 中。因此,不能够通过运行下面的语句获取它们。
*******************************************************************************************************************************************
第8章 泛型程序设计
*******************************************************************************************************************************************
1、为什么要使用泛型程序设计
1)泛型提供了一个更好的解决方案: 类型参数( type parameters)。ArrayList 类有一个类型 参数用来指示元素的类型: ArrayList<String> files = new ArrayList<String>():
在JavaSE7及以后的版本中, 构造函数中可以省略泛型类型:ArrayList<String> files = new ArrayList<>();// 不懂 但会用!
2、定义简单泛型类
这里的使用,和我定义的PageService有异曲同工之妙,面向接口编程的好处。
3、泛型方法:可以将结果賦给 Object、Serialiable 或 Comparable。约束和泛型配合工作才是最好的!
4、类型变量的限定: public static <T> T in(T[] a) // almost correct
5、泛型代码和虚拟机:虚拟机没有泛型类型对象—所有对象都属于普通类。在泛型实现的早期版本中, 甚至 能够将使用泛型的程序编译为在 1.0 虚拟机上运行的类文件!这个向后兼容性在 Java 泛型开 发的后期被放弃了。
6、约束与局限性
7、泛型类型的继承规则
8、通配符类型:通配符类型中, 允许类型参数变化。 例如, 通配符类型 Pair<? extends Employee〉 表示任何泛型 Pair 类型, 它的类型参数是 Employee 的子类, 如 Pair<Manager>, 但不是 Pair<String>。
9、反射和泛型:现在, Class 类是泛型的。例如, String.class 实际上是一个Class<String> 类的对象(事实上,是唯一的对象)。
*******************************************************************************************************************************************
第9章 集合
*******************************************************************************************************************************************
1、Java 集合框架 List Set Map Collection Queue
2、具体的集合
3、映射 Map k v对
4、视图与包装器
5、算法:泛型集合接口有一个很大的优点, 即算法只需要实现一次。例如, 考虑一下计算集合中 最大元素这样一个简单的算法。 使用传统方式, 程序设计人员可能会用循环实现这个算法。 下面就是找出数组中最大元素的代码
6、遗留的集合:Hashtable 枚举 栈
*******************************************************************************************************************************************
第10章 图形程序设计GUI
*******************************************************************************************************************************************
1、Swing 概述 在ARM机器上界面交互还是有用的!!!
2、创建框架:在 Java 中,顶层窗口(就是没有包含在其他窗口中的窗口)被称为框架(frame )。在 AWT 库中有一个称为 Frame 的类, 用于描述顶层窗口。这个类的 Swing 版本名为 JFrame, 它扩展于 Frame 类。JFrame 是极少数几个不绘制在画布上的 Swing 组件之一。因此,它的修 饰部件(按钮、标题栏、图标等)由用户的窗口系统绘制, 而不是由 Swing 绘制。
3、框架定位:JFrame 类本身只包含若干个改变框架外观的方法。当然,通过继承, 从 JFrame 的各个 超类中继承了许多用于处理框架大小和位置的方法 其中最重要的有下面几个setLocation...。
4、在组件中显示信息
5、处 理 2D 图形:自从 Java 版本 1.0 以来, Graphics 类就包含绘制直线、矩形和楠圆等方法。但是,这些 绘制图形的操作能力非常有限。例如, 不能改变线的粗细,不能旋转这些图形。
6、使用颜色:使用 Gr叩hics2D 类的 setPaint 方法可以为图形环境上的所有后续的绘制操作选择颜色。
7、文本使用特殊字体
8、显示图像:到目前为止,我们已经看到了如何通过绘制直线和图形创建一个简单的图像。而对于照片这样的复杂图像来说,通常都是由扫描仪或特殊的图像处理软件生成的(正像在卷n中将看到的,逐像素地生成图像。
*******************************************************************************************************************************************
第11章 事件处理【佩服自己,2章内容自己1个帖子拿捏】【483页】
*******************************************************************************************************************************************
1、事件处理基础:任何支持 GUI 的操作环境都要不断地监视按键或点击鼠标这样的事件。操作环境将 这些事件报告给正在运行的应用程序。如果有事件产生,每个应用程序将决定如何对它们 做出响应。在 Visual Basic 这样的语言中, 事件与代码之间有着明确的对应关系。程序员 对相关的特定事件编写代码, 并将这些代码放置在过程中,通常人们将它们称为事件过 程( event procedure) 0 例如,有一个名为 HelpButton 的 Visual Basic 按钮有一个与之关联的 HelpButton_Click 事件过程。这个过程中的代码将在点击按钮后执行。每个 Visual Basic 的 GUI 组件都响应一个固定的事件集,不可能改变 Visual Basic 组件响应的事件集。
2、动作:通常, 激活一个命令可以有多种方式。用户可以通过菜单、击键或工具栏上的按钮选择 特定的功能。在 AWT 事件模型中实现这些非常容易:将所有事件连接到同一个监听器上。 例如, 假设 blueAction 是一个动作监听器,它的 actionPerformed方法可以将背景颜色改变成 蓝色。将一个监听器对象加到下面几个事件源上:
3、鼠标事件:如果只希望用户能够点击按钮或菜单,那么就不需要显式地处理鼠标事件。鼠标操作将 由用户界面中的各种组件内部处理。然而, 如果希望用户使用鼠标画图, 就需要捕获鼠标移 动点击和拖动事件。
4、AWT 事件继承层次:弄清了事件处理的工作过程之后,作为本章的结束, 总结一下 AWT 事件处理的体系架构。 前面已经提到,Java 事件处理采用的是面向对象方法,所有的事件都是由 java.util 包中 的 EventObject 类扩展而来的(公共超类不是 Event, 它是旧事件模型中的事件类名。尽管现 在不赞成使用旧的事件模型,但这些类仍然保留在 Java 库中)。 EventObject 类有一个子类 AWTEvent,它是所有 AWT 事件类的父类。 图 11-8 显示了 AWT 事件的继承关系图。
*******************************************************************************************************************************************
第12章 SWING用户界面组件
*******************************************************************************************************************************************
1、Swing 与模型 -视图 -控制器设计模式:MVC模式 模型【数据库】 视图【VIEW】 控制器【CONTROLLER】
2、布局管理概述:Flow布局 xy定位
3、文本输入:获取文本进行GUI交互
4、选择组件:类似VUE什么场景用什么组件
5、菜单:各种按钮、 文本域以及组合框等。 Swing 还提供了一些其他种类的用户界面兀素’ 下拉式菜单就是 GUI 应用程序中很常见的一种。
6、复杂的布局管理:迄今为止, 在前面的示例应用程序所使用的用户界面组件中, 只使用了边框布局、 流布布局和网格布局。对于复杂的问题而言, 只使用这四种布局显然不够。 本节将详细地讨论高级布局管理器。好像并不需要。
7、对话框:与大多数的窗口系统一样, AWT 也分为模式对话框和无模式对话框。所谓模式对话框是 指在结束对它的处理之前, 不允许用户与应用程序的其余窗口进行交互。模式对话框主要用 于在程序继续运行之前获取用户提供的信息。例如, 当用户想要读取文件时,就会弹出一个核心技术。 模式对话框。用户必须给定一个文件名, 然后程序才能够开始读操作。只有用户关闭(模式) 对话框之后, 应用程序才能够继续执行。在VUE中可以简单的使用了吧...
8、GUI程序排错:本节会给出 GUI 编程的一些调试技巧, 然后介绍如何使用 AWT 机器人 ( AWT robot ) 自 动完成 GUI 测试。
*******************************************************************************************************************************************
第13章 部署Java应用程序
*******************************************************************************************************************************************
1、JAR 文件:在将应用程序进行打包时,使用者一定希望仅提供给其一个单独的文件,而不是一个含 有大量类文件的目录,Java 归档(JAR) 文件就是为此目的而设计的。一个 JAR 文件既可以 包含类文件,也可以包含诸如图像和声音这些其他类型的文件。此外, JAR 文件是压缩的, 它使用了大家熟悉的 ZIP 压缩格式。
2、应用首选项的存储:应用用户通常希望能保存他们的首选项和定制信息, 以后再次启动应用时再恢复这些配置。首先我们来介绍 Java 应用的传统做法, 这是一种简单的方法,将配置信息保存在属性文 件中。然后我们会介绍首选项 API, 它提供了一个更加健壮的解决方案。用文件替代数据库。
3、服务加载器:跨平台插件
4、applet:过时的技术
5、Java Web Start:要想准备一个通过 Java Web Start 发布的应用程序, 应该将其打包到一个或多个 JAR 文 件中。然后创建一个 Java Network Launch Protocol ( JNLP ) 格式的描述符文件。将这些文件 放置在 Web 服务器上。也成为过去时了。要借助tomcat
*******************************************************************************************************************************************
第14章 并发【641】
*******************************************************************************************************************************************
1、什么是线程:这里从察看一个没有使用多线程的程序开始。用户很难让它执行多个任务。在对其进行 剖析之后,将展示让这个程序运行几个彼此独立的多个线程是很容易的。这个程序采用不断 地移动位置的方式实现球跳动的动画效果,如果发现球碰到墙壁, 将进行重绘。可以将移动球的代码放置在一个独立的线程中, 运行这段代码可以提高弹跳球的响应能力。实际上,可以发起多个球,每个球都在自己的线程中运行。这不就是坦克大战的子弹吗。
2、中断线程:当线程的 run 方法执行方法体中最后一条语句后, 并经由执行 return 语句返冋时,或者 第 1 4 章 并 6 3 3 出现了在方法中没有捕获的异常时,线程将终止。 在 Java 的早期版本中, 还有一个 stop 方 法, 其他线程可以调用它终止线程。但是, 这个方法现在已经被弃用了。14.5.15 节将讨论它 被弃用的缘由。
3、线程状态:线程可以有如下 6 种状态: •New (新创建) •Runnable (可运行) •Blocked (被阻塞) •Waiting (等待) •Timed waiting (计时等待) •Terminated (被终止)
4、线程属性:下面将讨论线程的各种属性,其中包括:线程优先级、守护线程、 线程组以及处理未捕 获异常的处理器。守护线程(daemon thread)。这样一个线程没有什么神奇。守护线程的唯一用途是为其他线程提供服务。
5、同步:在大多数实际的多线程应用中, 两个或两个以上的线程需要共享对同一数据的存取。如 第 1 4 章 并 ? 6 4 1 果两个线程存取相同的对象, 并且每一个线程都调用了一个修改该对象状态的方法,将会发 生什么呢? 可以想象, 线程彼此踩了对方的脚。根据各线程访问数据的次序,可能会产生i化 误的对象。这样一个情况通常称为竞争条件(race condition)。有两种机制防止代码块受并发访问的干扰。Java语言提供一个 synchronized 关键字达 到这一目的,并且 Java SE 5.0 引入了 ReentrantLock 类。synchronized 关键字自动提供一个 锁以及相关的“ 条件”, 对于大多数需要显式锁的情况, 这是很便利的。但是, 我们相信在 读者分別阅读了锁和条件的内容之后, 理解 synchronized 关键字是很轻松的事情。java.util. concurrent 框架为这些基础机制提供独立的类,在此以及第 14.5.4 节加以解释这个内容
6、阻塞队列:对于许多线程问题, 可以通过使用一个或多个队列以优雅且安全的方式将其形式化。生 产者线程向队列插人元素, 消费者线程则取出它们。使用队列,可以安全地从一个线程向另 一个线程传递数据。
7、线程安全的集合:如果多线程要并发地修改一个数据结构, 例如散列表, 那么很容易会破坏这个数据结构 (有关散列表的详细信息见第 9 章 )。例如, 一个线程可能要开始向表中插入一个新元素。假 定在调整散列表各个桶之间的链接关系的过程中, 被剥夺了控制权。如果另一个线程也开始 遍历同一个链表,可能使用无效的链接并造成混乱, 会抛出异常或者陷人死循环。
8、Callable 与 Future:Runnable 封装一个异步运行的任务,可以把它想象成为一个没有参数和返回值的异步方 法。Callable 与 Runnable 类似,但是有返回值。Callable 接口是一个参数化的类型, 只有一 个方法 call。
9、执行器:执行器( Executor) 类有许多静态工厂方法用来构建线程池, 表 14-2 中对这些方法进行 了汇总。先来看一下表 14-2 中的 3 个方法。在第 14.9.2 节中,我们讨论其余的方法。newCachedThreadPoo丨方法构建了一个线程池, 对于每个任务, 如果有空闲线程可用,立即让它执行 任务,如果没有可用的空闲线程, 则创建一个新线程。newFixedThreadPool 方法构建一个具 有固定大小的线程池。 如果提交的任务数多于空闲的线程数, 那么把得不到服务的任务放 置到队列中。当其他任务完成以后再运行它们。
10、同步器:java.util.concurrent 包包含了几个能帮助人们管理相互合作的线程集的类见表 14-5。这 些机制具有为线程之间的共用集结点模式(common rendezvous patterns) 提供的“ 预置功能” ( canned functionality ) 0 如果有一个相互合作的线程集满足这些行为模式之一, 那么应该直接 重用合适的库类而不要试图提供手工的锁与条件的集合。
11、线程与 Swing:但是,必须认真考虑工作器线程在做什么,因为这或许令人惊讶,Swing 不是线程安全的。如果你试图在多个线程中操纵用户界面的元素,那么用户界面可能崩溃。
*******************************************************************************************************************************************
*******************************************************************************************************************************************
第15章 Java设计模式
*******************************************************************************************************************************************
1、设计模式概念
1)Java设计模式是一种反复使用的代码设计总结,设计模式的目的是重用代码、让代码容易被他人所理解、同时也保证了代码的可靠稳定性。在日常的项目开发中,合理的使用设计模式可以完美的解决对应的问题。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2、分类
建造者模型(5种)
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
结构型模式(7种)
适配器模式、装饰器模式、代理模式、桥接模式、外观模式、组合模式、享元模式
行为型模式(11种)
策略模式、模板方法模式、观察者模式、责任链模式、访问者模式、
中介者模式、迭代器模式、命令模式、状态模式、备忘录模式、解释器模式
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
3、设计模式的六大原则
1)开闭原则
开闭原则指的是对扩展开放,对修改关闭。在对程序进行扩展的时候,不能去修改原有的代码,想要达到这样的效果,我们就需要使用接口或者抽象类!!!
2) 依赖倒转原则
依赖倒置原则是开闭原则的基础,指的是针对接口编程,依赖于抽象而不依赖于具体
3) 里氏替换原则
里氏替换原则是继承与复用的基石,只有当子类可以替换掉基类,且系统的功能不受影响时,基类才能被复用,而子类也能够在基础类上增加新的行为。所以里氏替换原则指的是任何基类可以出现的地方,子类一定可以出现。
里氏替换原则是对 “开闭原则” 的补充,实现 “开闭原则” 的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏替换原则是对实现抽象化的具体步骤的规范。
4)接口隔离原则
使用多个隔离的接口,比使用单个接口要好,降低接口之间的耦合度与依赖,方便升级和维护方便!!!
5)迪米特原则
迪米特原则,也叫最少知道原则,指的是一个类应当尽量减少与其他实体进行相互作用,使得系统功能模块相对独立,降低耦合关系。该原则的初衷是降低类的耦合,虽然可以避免与非直接的类通信,但是要通信,就必然会通过一个“中介”来发生关系,过分的使用迪米特原则,会产生大量的中介和传递类,导致系统复杂度变大,所以采用迪米特法则时要反复权衡,既要做到结构清晰,又要高内聚低耦合。
6)合成复用原则
尽量使用组合/聚合的方式,而不是使用继承。!!!
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
4、这里我们只介绍几种设计模式的使用,这些一般在日常开发当中,是够使用的。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
5、单例设计模式
所谓单例设计模式简单说就是无论程序如何运行,采用单例设计模式的类(Singleton类)永远只会有一个实例化对象产生。具体实现步骤如下:
将采用单例设计模式的类的构造方法私有化(采用private修饰)。
在其内部产生该类的实例化对象,并将其封装成private static类型。
定义一个静态方法返回该类的实例。
public class AIMain {
public static void main(String[] args) throws Exception {
Singleton s1 = null; // 声明对象
Singleton s2 = null; // 声明对象
Singleton s3 = null; // 声明对象
s1 = Singleton.getInstance(); // 取得实例化对象
s2 = Singleton.getInstance(); // 取得实例化对象
s3 = Singleton.getInstance(); // 取得实例化对象
s1.print(); // 调用方法
s2.print(); // 调用方法
s3.print(); // 调用方法
}
}
class Singleton {
private static Singleton instance = new Singleton();// 在内部产生本类的实例化对象
public static Singleton getInstance() { // 通过静态方法返回instance对象
return instance;
}
private Singleton() { // 将构造方法封装为私有化
}
public void print() {
System.out.println("陈翔六点半");
}
}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
6、单例模式介绍
Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点
1)饿汉式,线程安全 但效率比较低
/**
*
* 单例模式的实现:饿汉式,线程安全 但效率比较低
*/
public class SingletonTest {
private SingletonTest() {
}
private static final SingletonTest instance = new SingletonTest();
public static SingletonTest getInstancei() {
return instance;
}
}
2)单例模式的实现:饱汉式,非线程安全
/**
* 单例模式的实现:饱汉式,非线程安全
*
*/
public class SingletonTest {
private SingletonTest() {
}
private static SingletonTest instance;
public static SingletonTest getInstance() {
if (instance == null)
instance = new SingletonTest();
return instance;
}
}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
工厂模式详解(简单工厂+工厂方法+抽象工厂)
工厂模式将目的将创建对象的具体过程屏蔽隔离起来,从而达到更高的灵活性,工厂模式可以分为三类:
简单工厂模式(Simple Factory)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)