java 自学笔记 基础篇

1、 Day01;
1. Java的架构(如下图);

2. Java环境的搭建,jdk的安装与配置;
a、 Jdk的安装;
直接下一步就ok了
b、 Jdk的配置;
当我们写完一个java程序时要想看到结果,首先将对其进行编译,然后再执行,其中编译是交给jdk安装目录中bin文件夹里的javac来对*.java文件进行编译,使之生成java虚拟机(JVM)能够解释的*.class字节码文件,这样才能将效果显示出来。
Path;在我们还没有将jdk的执行语句配置到系统环境变量中,这样会使我们每次编译的时候都会跑到bin目录中,然后在执行其中相应的命令,比如:javac、java等执行命令。所以为了减少不必要的麻烦,我们就将jdk安装目录中bin放进系统的环境变量之中,之前有很多的路径,我们可以用(;英文的分号)来隔开,比如:(;C:\Program Files\Java\jdk1.7.0_03\bin;)这样设置之后,我们就可以将jdk的bin文件夹里的执行命令当做系统命令来使用了。
Classpath;编译好我们的java文件之后,我们就需要通过java来执行了,第一过程是首先先找到字节码文件存在的路径,就是在java文件所存在的路径,也就是当前路径(用.来表示),但是java文件是通过jdk中的类库对象去写的,所以第二还要找到类库对象存在的路径(jdk中的lib目录中),这2个路径组成另外一个环境变量classpath的路径,即(. ;C:\Program Files\Java\jdk1.7.0_03\lib;)
Javahome;它是指jdk的安装目录,像C:\Program Files\Java\jdk1.7.0_03。可以新建一个JAVA_HOME变量,它的取值为C:\Program Files\Java\jdk1.7.0_03。为什么要设置它呢,不设定可不可以呢?不设定也是可以滴,但是最好还是设置一下。我们现在就当它是一个变量代换 JAVA_HOME = C:\Program Files\Java\jdk1.7.0_03,就是为了避免多写字,它还有一个好处就是当我们需要改变某个jdk时,只需要改JAVA_HOME的值就可以了。Tomcat启动时会用得到的。
3. 第一个HelloWorld常见的错误;
c、 错误1;
一个类文件比如HelloWorld.java中可以包含有很多个类名(比如HelloWorld,Students,Test、、、、),但是只能有一个类名是带public修饰符号的,而且只能有一个这样的类名是跟类的文件名称一直。否则编译不过。
d、 错误2;
一个类文件中包含有多少个类名,如果编译通过了,就会生成多少个相对应的字节码文件。如果通过Java命令去执行字节码文件,意味着虚拟机开始与主方法(main方法)挂钩,如果找不到,会出现这样的错误。
Exception in thread "main" java.lang.NoSuchMethodError: main
e、 错误3;
类文件HellWorld.java是不区分大小写,但是类名或者字节码文件是区分大小写的。这是在编译和执行的时候有这么一种说法,但是类的文件名称或者类名的命名规则是:每个单词的首字母都要大小。
f、 错误4;
主方法必须是sun规定的主方法,造型必须是public static void main(String[] 参数名称){}
g、 错误5;
使用英文字符下的标点符号,不要使用中文字符下的。否则会出现“非法字符”的错误。
2、 Day02;
4. 类的结构;
h、 属性(当需要的可以写进来);
i、 构造方法(一定需要的,系统会默认给他一个无参的构造方法);
j、 自定义方法(当需要的可以写进来);
k、 主方法(当需要的可以写进来);
5. 如何定义属性;
l、 结构;
访问权限 + 返回类型 + 属性名称 = 初始化值
A、 访问权限(4个)从大到小的排序;
Public ------------------> 公开的:可以访问这个工程下的所有的包下的类都可以访问。
Protected --------------> 受保护的:只能在同一个包下的类去访问,或者不同包下的子类也可以访问。
默认 ------------------> 默认什么都没有写的: 只能在同一包下的类去访问。
Private ---------------> 私有的:只能在本类中去访问的。
B、 返回类型(可以分两类);
a、 基本数据类型
整型数据类型
Byte:字节型(1个字节,8位)
Short:短整型(2个字节,16位)
Char:字符型(2个字节,16位)
Int:整型(4个字节,32位)
Long:长整型(8个字节,64位)
布尔类型
Boolean:布尔类型(1个字节,8位)true或者false
浮点类型
Float:单精度浮点型(4个字节,32位)
Double:双精度浮点型(8个字节,64位)
b、 引用数据类型
类库类型:String类型等sun公司写的类库类型;
自定义的引用类型:Student类;
数组类型:int[] values = new int[2];
C、 属性;
属性:也称为是成员的属性,级别是跟方法一样的。属性是写在方法之外的。
属性可以分为:
全局变量
结构:访问权限+返回类型+变量名称=可以初始化,或者不初始化。
命名规则:从第二个单词以后的每个单词的首字母必须大写,其他的小写。
特点:变量的值是可以修改的,是可以改变的。
a、 返回类型是整形数据类型的基本数据类型,默认值是0
b、 返回类型是布尔类型,默认值是false
c、 返回类型是浮点类型,默认值是0.0或者0.0f
d、 返回类型是引用类型,默认值是null
常量
结构:结构:访问权限 + 返回类型 + 变量的名称 = 必须初始化
命名规则:全部字母必须是大写的。
特点:是被final来修饰的,常量的值是不可以修改的。
6. 如何定义构造方法;
m、 结构;
访问权限 + 类名 () {}
n、 分类;
D、 无参构造方法;
系统会默认一个无参的构造方法。
E、 有参构造方法;
在()里放了一些参数列表的构造方法。
F、 两者比较相同与不同;
相同的地方:
都是可以为属性进行赋值
不同的地方:
无参数的构造方法已经为属性的值写死了。但是有参数的值没有给定,是给调用的人去它赋值。
说明:
如果写了有参数的构造方法,那么会将系统中默认的无参数的构造方法覆盖掉但是通常无参数的构造方法都要写到类的里边去
3、 Day03;
7. 如何自定义方法;
o、 结构;
访问权限 + 返回类型/void + 方法名称(){}
G、 访问权限;
跟定义属性时候的访问权限一样。
当方法有返回类型的时候,这个返回类型跟定义属性时候的返回类型一样。当方法没有返回类型的时候,那么用void来表示。
H、 方法的定义分为两块;
方法的声明部分:public void test()
方法的实现部分{}
I、 方法的命名规则;
跟定义的属性时候的全局变量的命名规则是一样的。
J、 ();
表示方法的参数列表,里边的个数可以使0到N个。
K、 参数的结构;
返回类型 + 参数名称
L、 {};
方法体,也称为方法的实现部分。所有的操作代码度可以写在{}里边的。
M、 局部变量与全局变量的区别;
局部变量
定义的位置:定义在方法体中的变量。
作用域:只是针对本方法可以访问的变量。
结构:反回类型 + 局部变量 = 一定要初始化。

全局变量
定义的位置:定义方法的外边,也就是属性中的全局变量。
作用域:所有的方法都可以访问的变量。
结构:访问权限 + 返回类型 + 全局变量的名称 = 可以不初始化
N、 参数与局部变量?什么时候该使用的?
参数
每个人强调用的值都是动态的。
局部变量
每个人调用的值都是固定的。
8. 主方法;
p、 Sun规定的main方法(或者程序的入口方法)
O、 public关键字;
这个好理解,声明主函数为public就是告诉其他的类可以访问这个函数。

P、 (2)static关键字;
告知编译器main函数是一个静态函数。也就是说main函数中的代码是存储在静态存储区的,即当定义了类以后这段代码就已经存在了。如果main()方法没有使用static修饰符,那么编译不会出错,但是如果你试图执行该程序将会报错,提示main()方法不存在。因为包含main()的类并没有实例化(即没有这个类的对象),所以其main()方法也不会存。而使用static修饰符则表示该方法是静态的,不需要实例化即可使用。

Q、 void关键字表明main()的返回值是无类型;
R、 参数String[] args,这是本文的重点;
第一、程序使用者可以在命令行状态下向某个类传递参数。
看下面的例子:
package mySelf;

/**
* 这是一个测试main的类;
*
* @author zouguoliang
*
*/
public class MainDemo {
public static void main(String[] args) {
String str = new String();
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
str += args[i];
}
System.out.println(str);
}
}
使用javac MainDemo.java命令生成MainDemo.class文件;然后使用“java MainDemo参数一 参数二 参数三 …”的格式向MainDemo类传递参数。该示例程序将首先输出参数,然后输出所有参数的和。比如java MainDemo 23 34 sdf 65 123 drfg asd,将得到这样的输出:
23
34
sdf
65
123
drfg
asd
2334sdf65123drfgasd
*需要注意的是,如果这里的循环条件不是i <args.length,而是i <5,则在命令行中输入的参数必须是5个,否则将会报错,错误类型为:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at MainDemo.main(MainDemo.java:5)
第二、可以在另一个类中向包含main()的类传递参数;
如下例子;

总结:
参数args的主要作用是为程序使用者在命令行状态下与程序交互提供了一种手段。此外在其他类中直接使用main()函数,并传递参数也是可行的,虽然这种方法不太常用,但毕竟为我们提供了一种选择。
9. Stu与Stu2的区别(如下图){堆和栈以及变量和引用的区别};

10. 练习题;
计算工资的类:
1、刚入职的基本工资:比如一开始给的是6K(基本工资是动态的,每个人都是不一样)
2、总的工龄工资(老板给你加的薪水):(提示:要根据工龄和满1年的工龄工资去计算)
规定:刚入职也就是工龄 = 0年的时候,没有工龄工资
当工作满1年的时候,才有工龄工资,比如工龄工资 = 1000元(工龄工资也是动态的,每个人都不一样)
以后每多工作1年,那么工龄工资就相当于上一年的1.2倍。
3、总工资:
总工资 = 刚入职的基本工资 + 总的工龄工资。
4、实际获得的工资待遇:
实际的工资待遇 = 总工资 - 交税 - 住房公积金。
交税和住房公积金的比例:
如果总工资在 3500元以下,不需要交税,住房公积金交总工资里边的2%
如果总工资在3500 - 8000元之间,需要交税3%,住房公积金交剩余里边的3%。
如果总工资在8000 - 15000元之间,需要交税4%,住房公积金交剩余里边的5%。
如果总工资在15000元以上,需要交税5%,住房公积金交剩余里边的7%。
代码:
package Tring;
public class SalaryManager {
// 定义一个总工资的变量
public double sumSalary;
// 定义一个实际获得的工资待遇的变量
public double factSalary;
/**
*
* @param firstWorkAgeSalary
* :满1年的工龄工资
* @param workAge
* :工龄
* @return:返回总的工龄工资
*/
public double getSumWorkAgeSalary(double firstWorkAgeSalary, int workAge) {
// 定义总的工龄工资的局部变量
double sumWorkAgeSalary = 0;
// 定义某年的工龄工资
double nWorkAgeSalary = 0;
if (workAge == 0) {
sumWorkAgeSalary = 0;
} else {
// 刚满1年才有工龄工资
nWorkAgeSalary = firstWorkAgeSalary;
sumWorkAgeSalary = nWorkAgeSalary;

for (int i = 2; i <= workAge; i++) {
// 算出某年的工龄工资(workAge >= 2)
nWorkAgeSalary = nWorkAgeSalary * 1.2;
// 计算n年来的总的工龄工资
sumWorkAgeSalary = sumWorkAgeSalary + nWorkAgeSalary;
}
}
return sumWorkAgeSalary;
}

/**
* 计算总的工资的方法
*
* @param firstBasicSalary
* :刚入职的基本工资
* @param firstWorkAgeSalary
* :满1年的工龄工资
* @param workAge
* :工龄
* @return:返回总的工资
*/
public double getSumSalary(double firstBasicSalary,
double firstWorkAgeSalary, int workAge) {
sumSalary = firstBasicSalary
+ getSumWorkAgeSalary(firstWorkAgeSalary, workAge);
return sumSalary;
}

/**
* 计算获得的工资待遇
*
* @return
*/
public double getFactSalary() {
if (sumSalary < 3500) {
factSalary = sumSalary * (1 - 0.02);
} else if (sumSalary >= 3500 && sumSalary < 8000) {
factSalary = sumSalary * (1 - 0.03) * (1 - 0.03);
} else if (sumSalary >= 8000 && sumSalary < 15000) {
factSalary = sumSalary * (1 - 0.04) * (1 - 0.05);
} else {
factSalary = sumSalary * (1 - 0.05) * (1 - 0.07);
}
return factSalary;
}

public static void main(String[] args) {
SalaryManager manager = new SalaryManager ();
manager.sumSalary = manager.getSumSalary(5000, 2000, 2);
System.out.println("总的工资为:" + manager.sumSalary);
manager.factSalary = manager.getFactSalary();
System.out.println("实际的工资待遇为:" + manager.factSalary);
}
}
4、 Day04;
11. 条件判断语句;
q、 if……else的嵌套;
对某个区间进行判断
也可以对某个定点进行判断
代码:
/**
* 比较两个整数的大小;
* @author zouguoliang;
*/
import java.util.Scanner;

public class Ifelse {
public static void main(String[] args) {
System.out.println("====请输入X值====");
Scanner scanner_X = new Scanner(System.in);
int x = scanner_X.nextInt();
System.out.println("====请输入Y值====");
Scanner scanner_Y = new Scanner(System.in);
int y = scanner_Y.nextInt();
System.out.println("=================");
if (x > y) {
System.out.println("x的值比y大");
} else {
System.out.println("y的值比x大");
}
}
}
r、 switch……case;
只能针对某个定点进行判断,但是执行效率比if条件判断高。
switch……case 里边会直接去找那个条件,但是if是从第一个开始进行匹配,知道成立的那个条件位止。
package Tring;

import java.util.Scanner;

public class SwitchCase {
public static void main(String[] args) {
System.out.println("====请输入你的分数====");
Scanner scanner_Score = new Scanner(System.in);
int score = scanner_Score.nextInt();
switch (score) {
case 60:
System.out.println("你的成绩刚刚好及格!");
break;
case 70:
System.out.println("你的成绩还可啦!");
break;
case 100:
System.out.println("你的成绩优秀!");
break;
default:
break;
}
}
}
12. 循环语句;
s、 for循环;
S、 用for循环打印60到100;
public class LoopManager {
public static void main(String[] args) {
for(int score = 60; score <= 100; score ++){
System.out.println("score = " + score);
}
}
}
for循环那么它到底是如何打印的呢?
for循环执行的顺序是如何的呢?
1、初始值int score = 60也要去条件score<=100中去判断,如果成立就执行for语句块中的代码。
2、for循环执行完一次,会执行score ++(累加,表示 + 1)。也要去条件score <= 100中去判断。
3、直到判断条件不满足时结束for循环。
t、 do……while循环;
T、 用do……while打印60到100;
public class LoopManager {
public static void main(String[] args) {
int x = 60;
do{
System.out.println("x = " + x);
x ++;
}while(x <= 100);
}
}
原理:
do...while循环的int x = 60不需要到while(x<=100)中去判断。
也会执行一次打印的效果。从第二次之后的值才需要到条件中去判断。
u、 while循环;
U、 用while打印60到100;
public class LoopManager {
public static void main(String[] args) {
int y = 60;
while(y <= 50){
System.out.println("y = " + y);
y ++;
}
}
原理:
跟for循环的一样。
13. 数组;
v、 概念;
之前的基本数据类型的变量或引用类型(自定义类型以及类库类型)都只能保存一种数据。但是现在如果有多个数据需要保存,那么必须使用数组类型的变量来保存。
w、 特点;
数组类型的变量只能保存同种类型的元素。比如定义一个int类型的数组:int[] values = new int[4],表示values里边有4个int类型的元素;
x、 如何创建数组;
I、 String[] values = null;
II、 String values[] = null;
y、 如何定义数组(实例化);
I、 int[] values = new int[4]; ------ 表示里边有4个int类型的元素。每个元素独有默认值;
II、 int[] values = {21,34,234,34}; ------ 表示里边有4个元素,同时指定了各个元素的值。
III、 数组中的元素一旦确定了之后,就不能改变其大小,也不可以修改其中元素的值。不能进行增删操作。这个时候就不能使用数组来保存数据而且只能用集合来保存。
IV、 数组的排序功能。使用Array下的sort方法,是能够对各种类型的数组进行值的排列;
代码:
package Tring.loop;

import java.util.Arrays;

public class Sortdemo {
/**
* 自定义一个数组排序的方法;
*/
public void arraySort() {
// 给数组赋值;
int[] values = { 2134, 5463, 23, 56, 678, 12345 };
// 排序之前遍历数组;
System.out.println("==========排序之前的数组==========");
for (int i = 0; i < values.length; i++) {
System.out.println("values[ " + i + " ] = " + values[i]);
}
// 对values排序;
Arrays.sort(values);
// 排序之前遍历数组;
System.out.println("==========排序之后的数组==========");
for (int i = 0; i < values.length; i++) {
System.out.println("values[ " + i + " ] = " + values[i]);
}
}

public static void main(String[] args) {
Sortdemo sortdemo = new Sortdemo();
sortdemo.arraySort();
}
}
V、 数组的拷贝功能,使用System下的arraycopy方法,对两个数组进行元素的拷贝;
代码:
package Tring.loop;

public class arrayCopy {
// 定义一个复制数组的方法;
public void copyArray() {
// 定义一个int类型的数组1;
int[] array1 = new int[7];
for (int i = 0; i < array1.length; i++) {
array1[i] = i + 1;
}
// 定义一个int类型的数组2;
int[] array2 = new int[10];
for (int i = 0; i < array2.length; i++) {
array2[i] = i + 30;
}
/**
* 从数组array1的3,4,5,6值拷贝到数组array2的5,6,7,8位置上,四个
*/
// 对数组进行复制;
System.arraycopy(array1, 2, array2, 4, 4);
// 打印array1
System.out.println(array2);
// 对array2数组进行遍历
for (int i = 0; i < array2.length; i++) {
System.out.println("array2[ " + i + " ]= " + array2[i]);
}
}

public static void main(String[] args) {
arrayCopy copy = new arrayCopy();
copy.copyArray();
}
}
z、 练习题;
定义一个初始化数组的方法
定义一个遍历数组的方法,但是前提这2个方法都是动态。
代码1:
练习题:
package Tring.loop;

/**
* 动态定义数组,并打印;
*
* @author zouguoliang
*
*/
public class DefineArray {
// 初始化数组
public void initArray(Object[] objectArray) {
for (int i = 0; i < objectArray.length; i++) {
// objectArray[i] = Integer.valueOf(i + 1).toString();
objectArray[i] = "" + (i + 1);
}
}

// 打印数组;
public void printArray(Object[] objectArray) {
for (int i = 0; i < objectArray.length; i++) {
System.out.println("objectArray[" + i + "] = " + objectArray[i]);
}
}

public static void main(String[] args) {
DefineArray defineArray = new DefineArray();
String[] values = new String[4];
defineArray.initArray(values);
defineArray.printArray(values);
}
}

代码2:
package Tring.loop;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

/**
* 动态定义数组,并打印;
*
* @author zouguoliang
*
*/
public class DefineArray {
/**
* 定义一个键盘输入数组的方法;
*
* @return
*/
public Scanner getScanner() {
Scanner scanner = new Scanner(System.in);
// scanner.nextLine();
return scanner;
}

/**
* 定义一个键盘输入数组的方法;
*
* @param objectArray
*/
public BufferedReader getKey() {
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(System.in));
return bufferedReader;
}

/**
* 初始化数组方法;
*
* @param objectArray
*/
public void initArray(Object[] objectArray) {
BufferedReader bufferedReader = getKey();
System.out.println("请输入数组中的元素");
for (int i = 0; i < objectArray.length; i++) {
// objectArray[i] = Integer.valueOf(i + 1).toString();
System.out.println("请输入数组的第个 " + (i + 1) + " 元素");
try {
String data = bufferedReader.readLine();
objectArray[i] = data;
if (i == objectArray.length - 1) {
System.out.println("数组初始化完毕");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

// 打印数组;
public void printArray(Object[] objectArray) {
for (int i = 0; i < objectArray.length; i++) {
System.out.println("objectArray[" + i + "] = " + objectArray[i]);
}
}

public static void main(String[] args) {
DefineArray defineArray = new DefineArray();
String[] values = new String[4];
defineArray.initArray(values);
defineArray.printArray(values);
}
}
5、 Day05;
14. 面向对象的特性之一:封装
aa、 封装的概念;
可以理解成为是讲代码包装起来,为何需要包装?因为封装起来的代码都是通用性很强的代码,通常来说需要将这段代码隐藏的技术的细节。
bb、 封装是谁写的;
是由中间件或者框架或者底层架构这样的团队(都是骨灰级的程序员写的)去写的。写完之后就打包成*.jar的形式。然后生成相应的api的帮助文档,以后就可以被程序员调用了。
cc、 封装的种类;
V、 中间件或者框架;
比如ssh(Struts,Spring,Hibernate)
W、 JavaBean实体类对象
Javabean实体---------数据库表相对应---------模块
User实体类---------user_list---------用户模块
X、 接口中的属性和方法;
是由架构这个系统师去定义规范的,定义好了之后将相关的接口进行封装(*.jar形式),然后给程序员调用。
Y、 Javabean的写法;
A、Javabean的属性是与数据库中的字段相对应的(类型一定要匹配)
B、Javabean中的属性都是私有的(用private来修饰的),其他类想要访问这个javabean的话,就必须通过javabean中的set方法与get方法去访问。
Set方法:是为属性赋值的
Get方法:是获取属性的值
定义一个User类,代码:
package Tring.loop;

public class UserBean {
/**
* 定义一些User的一些属性;
*/
private String name;// 定义User的名字;
private String address;// 定义User的住址;
private int age;// 定义User的年龄;
private char sex;// 定义User的性别;

/**
* 生成一些列的set与get方法;
*/
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public char getSex() {
return sex;
}

public void setSex(char sex) {
this.sex = sex;
}
}
定义一个Test类测试,代码:
package Tring.loop;

import java.io.ObjectInputStream.GetField;

public class Test {

/**
* 这是一个Test类,用来测试User
*
* @param args
*/
public static void main(String[] args) {
UserBean userBean = new UserBean();
//赋值;
userBean.setName("邹国良");
userBean.setAge(22);
userBean.setAddress("广东轻工职业技术学院");
userBean.setSex("男");

System.out.println("姓名:" + userBean.getName() + "\n" + "住址为:"
+ userBean.getAddress() + "\n" + "年龄为:" + userBean.getAge()
+ " 岁" + "\n" + "性别:" + userBean.getSex());
}
}
Z、 Javabean在javaEE中的应用
通过四层架构来阐述;

6、 Day06;
dd、 面向对象的特性之二:继承;
AA、 继承的概念;
如果一个类A去继承一个类C,那么类A就可以去继承类C中可以继承的属性和自己的方法。
例子:
首先先定义一个Animal类:
package Day06;

public class Animal {
private String name = "动物";

public int age = 4;

/**
* 在此处一定要写Animal的无参构造方法,否则,在被其他类继承有参构造方法的时候会报错
*/
public Animal() {

}

public Animal(String name, int age) {
this.name = name;
this.age = age;
}

public void jiao() {
System.out.println(age + " 岁的 " + name + " 不会叫!");
}

public String yaoren() {
return age + " 岁的 " + name + " 不会咬人!";
}
}
然后再定义一个Cat类:
package Day06;

public class Cat extends Animal {
public String name;

public int age;

public Cat(String name, int age) {
this.name = name;
this.age = age;
}

public void jiao() {
System.out.println(age + " 岁的 " + name + " 会叫!!");
}

public String yaoren() {
return age + " 岁的 " + name + " 会咬人!!";
}

}
在定义一个Test类:
package Day06;

public class TestDemo {
public static void main(String[] args) {
Animal cat = new Animal("咖啡猫", 3);
cat.jiao();
System.out.println(cat.yaoren());
}
}
好了,到目前为止一个继承类就算完成了。
BB、 继承的优点;
II、 当子类中的方法的实现部分跟父类的方法的实现部分一致的时候,就用继承好点。
III、 在子类中不需要写相关的方法时候,在子类中还是可以调用父类的方法是为了节省子类的代码量。
CC、 重写;
当子类的方法的实现部分跟父类的实现的部分不一致的时候,就将父类中的方法进行重写或者改写或者覆盖。假如Cat中的叫的方法的实现部分跟父类Animal中的叫的方法不一致的时候,那么就重写这个方法(重新写一下这个方法)。
重写的条件:父类的声明在子类完全一样的搬下来,可以扩大其访问权限,也可以相等,但是不能缩小他的访问权限。
注意:重写是针对方法的重写,属性中没有重写的概念的。
DD、 重载概念;
在同一个类中有多个方法名称相同的方法(通常是在参数的列表里做文章)。
比如:println这个方法就是通过方法的重载来时实现的。可以打印各种数据类型的值(功能类似)但是传入的参数不一样(参数列表不一样)

代码:
package day06.jicheng.overload;

import java.util.ArrayList;
import java.util.List;

import day05.bean.User;

public class QueryManager {

public List<User> queryUser() {
return null;
}

/**
* 通过hibernate进行查询用户列表
*/
public List<User> queryUser(String hql) {
return null;
}

public List<User> queryUser(String sql, User user) {
return null;
}

private ArrayList<User> queryUser(User user, String sql) {
return null;
}
public static void main(String[] args) {
}
}
通过以上代码可以看出:
IV、 方法名称要相同
V、 参数列表不同(参数的个数不同,相对应的位置参数的返回类型不一样)。
VI、 跟方法本身的返回类型是没有关系的,也跟访问权限没有关系。
EE、 重写和重载的区别与联系;
重写是在父类关系的类中体现出来,但是重载是在一个类中体现出来。
重写的方法的声明部分要跟父类的一样(唯有访问权限可以相等或者扩大),但是重载只有跟方法名称和参数列表有关系,跟其他的没有关系。
FF、 继承与重写的调用方法的总结
I、 当方法继承的时候,调用的是父类的方法。
II、 当方法重写的时候,调用的是子类的方法。
III、 重写:采取的是最近的原则,那么执行子类方法的内容。
IV、 继承:执行的是父类的方法的内容。
V、 总结:通过多态的方式去执行方法的时候,首先写找的是子类的方法,如果子类中有该方法,呢么执行子类的方法(证明是重写下来的方法),如果子类中没有这个方法,那么执行的是父类的方法(证明是继承下来的方法)。
a、 面向对象的特性之二:多态;
GG、 多态的概念;
基于继承基础上延伸出来的一个特性,一个父类的类型,可以延伸出多个不同的子类。那也就是说一种类型(父类),出现了多种不同的形态(子类,主要从子类中的重写来表现出来)。
HH、 多态的种类;
父类的引用指向子类的实例。
接口的引用指向实现类的实例。
7、 Day07;
15. 面向对象的特性之四:抽象类和接口;
b、 抽象类;
II、 概念与定义;
在一个类中,只要存在一个或者一个以上的抽象方法的类就称之为抽象类。
Public abstract class Test{} -------- 就是定义抽象类的过程。
JJ、 抽象方法;
方法只有声明部分,没有实现部分的方法称之为抽象方法。
Public abstract void test();-------- 就是抽象方法的定义;
举个例子说明抽象类的使用。
代码:首先先定义一个Mao类:
package day07.abstr;

/**
* 抽象类

*/
public abstract class Mao {
private String name = "Qinshihuang";

public void jieFang() {
System.out.println(name + "实现了统一全中国!");
}

public abstract void shouFu();
}
在定义一个Deng类,继承Mao:
package day07.abstr;

/**
* 抽象类的特性一: 如果一个类A去继承一个抽象类C,那么类A就要将类C中的抽象的方法重写一遍。其类A也是一个抽象类。
*/
public abstract class Deng extends Mao {
private String name = "liubang";

public void gaiGe() {
System.out.println(name + "实现了战国统一!");
}

@Override
public abstract void shouFu();

}
在定义一个Jiang类,继承Deng:
package day07.abstr;

public abstract class Jiang extends Deng {
private String name = "dongzhe";

public void sanGe() {
System.out.println(name + "瓜分天下!");
}

@Override
public abstract void shouFu();

}
在定义个TaoGe类,继承Jiang;
package day07.abstr;

public abstract class TaoGe extends Jiang {
private String name = "caocao";

public void keXue() {
System.out.println(name + "提出了屯田!");
}

@Override
public abstract void shouFu();

}
在定义个PingGe类,继承TaoGe;
package day07.abstr;

/**
* 抽象类的特性之二: 抽象类可以有抽象方法,当然也可以没有抽象方法。
*
* 反过来,如果有抽象方法的类,那一定是抽象的类。
*/
public class PingGe extends TaoGe {
private String name = "liubei";

public void attackPhli() {
System.out.println(name + "暴打曹操!");
}

public void attackJP() {
System.out.println(name + "暴打一顿!");
}

public void attackVi() {
System.out.println(name + "暴打一顿!");
}

@Override
public void shouFu() {
System.out.println(name + "把台湾收复回来了!");

}

}
最后在定义个Test类用来测试;
package day07.abstr;

/**
* 抽象类的特点之三: 抽象类要实例化的时候,只能实例化非抽象子类的实例,抽象类不能实例化自己类的实例
*/
public class TestAbstract {

public static void main(String[] args) {
// 通过多态的方式去实例化
Mao mao = new PingGe();
Deng deng = new PingGe();
Jiang jiang = new PingGe();
TaoGe tao = new PingGe();
PingGe ping = new PingGe();

// jieFang是继承下来的方法
mao.jieFang();
// shouFu是重写下来的方法。
mao.shouFu();

deng.gaiGe();
deng.shouFu();

jiang.sanGe();
jiang.shouFu();

tao.keXue();
tao.shouFu();

ping.attackJP();
ping.attackPhli();
ping.attackVi();
ping.shouFu();

}
}
根据上面的代码可以看出抽象类的及格特点,如下;
KK、 抽象类的三个特点;
VII、 如果一个类A去继承一个类C,那么类A就要将类C的抽象方法重写一遍,则其类A也是一个抽象类。
VIII、 抽象类可以有抽象方法,也可以没有抽象方法,反过来就不行,也就是说,有抽象方法的类,那一定是抽象的类。
IX、 当抽象方法需要实例化的时候,只能实例化非抽象类的子类,抽象类不能实例化自己的实例。
LL、 何时使用抽象类;
II、 抽象类是由程序员自己定义的。
III、 由于一般情况下是不会定义抽象类的,因为抽象类是不能实例化,如果定义了一个抽象类,那么就代表了还需要定义他的非抽象的子类,但是如果在做项目过程中,为了临时转交任务的时候才需要定义为抽象类,这是为了转交任务的方便,以为一个类如果继承了抽象类,需要将抽象类中的抽象方法重写一遍,知道哪些方面是没有实现的。
IV、 如果万一需要使用到抽象方法的时候,那就使用后边的接口会更方便。
a、 接口;
A、 接口的概念;
是用来定义规范的,是架构整个系统的时候需要为每个模块定义一个接口。
B、 谁来定义接口;
是由架构师来定义的。
接口既然是一个规范,所以接口中里边的属性是不能改变的以及接口中的方法声明部分也是不能改变的。通过什么办法达到程序员去修改接口中属性和方法,通过经相关的接口打包(封装*.jar的文件),同时还生成api的文档。但是api的文档要能看到代码的注释,那就要系统架构师在写接口的代码的时候必须用标准的文档规范来注释代码。
C、 例子;
I、比如定义一个用户模块的接口,规定用户里边是有这么写功能:
注册;
登录;
查询;
修改;
删除;
现在系统架构师要将这个模块中的5个方法写到用户模块的接口中去
II、如何定义接口的名称;
接口是可以为程序员的业务逻辑(service)和数据访问层(dao)提供的接口,那现在可以定义这样的接口名称:IuserService,IuserDao
以上的几个方法是业务逻辑层中的方法,所以讲以上的5个方法写到IuserService接口中去。
III、 为接口打包;
步骤如下:


好了,*.jar包已经生成了。
IV、 导包;
将生成的*.jar文件放到已经建好的package下(lib包)。


好了,到目前为止。包就导入进来了。
V、 生成接口的文档;


好了,到目前为止,接口api也生成了,接下来就举一个例子吧;
VI、 例子;
代码(先定义一个UserService类):
package day07.abstr.Test;

import java.util.List;

import day05.bean.User;
import day07.inter.IUserService;

public class UserService implements IUserService{

@Override
public boolean deleteUser(int arg0) {
System.out.println("删除成功!!");
return false;
}

@Override
public boolean login(User arg0) {
// TODO Auto-generated method stub
return false;
}

@Override
public void modifyUser(User arg0) {
// TODO Auto-generated method stub

}

@Override
public List<User> queryUser() {
// TODO Auto-generated method stub
return null;
}

@Override
public boolean registerUser(User arg0) {
// TODO Auto-generated method stub
return false;
}
}
在定义一个测试类(Test);
package day07.abstr.Test;

public class Test {

/**
* @param args
*/
public static void main(String[] args) {
UserService userService = new UserService();
userService.deleteUser(3);
}
}
Ok,一个自己架构的接口类已完成。
D、 总结接口;
X、 接口中属性是常量,默认是被public static final来修饰;
Static int AGE = 20;
Public static final int AGE = 20;
Public ing AGE = 20;
Public static int AGE = 20;
以上这样的抽象类的属性的定义都是对的。
XI、 接口中的方法都是抽象的方法,默认是被public abstract来修饰;
public void test();
abstract void test();
public abstract test();
void test();
以上这样的抽象方法的定义都是对的。
E、 抽象类与接口的比较;
V、 定义时;
抽象类;public abstract class 类名{}
接口;public interface 接口名{}
VI、 定义属性时;
抽象类;无限制
接口;默认是被public static final 修饰,是一个常量来的
VII、 定义方法时;
抽象类;声明抽象类方法的时候必须加上abstract关键字,而且方法可以是抽象的,也可以是非抽象的.
接口;声明接口方法的时候,默认被public abstract来修饰,而且接口中所有的的都是抽象方法.
VIII、 何时使用;
抽象类;由程序员自己定义,在临时转交任务的时候定义的
接口;是一个规范,是由系统架构师定义的。
8、 Day08;
16. 数据类型之间的转换;
a、 基本数据类型之间的转换;

b、 引用类型之间的转换;
17. 基本数据域封装类之间的转换;
c、 每个基本数据类型都对应有一个自己的封装类;
byte----- Byte
char----Character
shortShort
int---Integer
long--Long
boolean-Boolean
float---Float
doubleDouble

请注意以下代码:
package day08.convert;
/**
* 定义一个父类;
* @author zouguoliang
*
*/

public class Father {

}

package day08.convert;
/**
* 定义一个子类;
* @author zouguoliang
*
*/
public class Son extends Father{

}

package day08.convert;
/**
* 定义一个类型转换类;
* @author zouguoliang
*
*/

public class ConvertManager {
public static void main(String[] args) {
// 基本数据类型之间的转换
// 由int---->long(向上转型)
int x = 30;
long y = x;
// 由long---->int:强制转换(向下转型)
long m = 20;
int n = (int) m;

// 引用类型之间的转换
// 有Son----->Father类型(向上转型)
Father f = new Son();// 多态
// Son s = (Son)new Father();//引用类型之间没有向下转型,也就是没有强转
}
}
总结:基本数据类型可以进行上下转换,而引用类型之间没有向下的转换,只有向上的转换(即多态,父类的引用指向子类的实例)。
d、 有2中方法可进行转换;
I、Jdk1.4的特性通过封装类的方法进行转换
II、Jdk1.4的特性自动封箱的功能。(直接赋值)
代码:
package day08.basic_fz;

public class FZManager {

public static void main(String[] args) {
// 由byte---->Byte
/**
* 1、jdk1.4的特性,那就通过封装类的方法 2、jdk1.5的特性,就可以通过自动封箱的功能(直接赋值)
*/
// 1、在Byte中找方法,传入的参数的byte,返回的类型是Byte
byte b1 = 20;
Byte b2 = new Byte(b1);
System.out.println(b1);
System.out.println(b2);

Byte b3 = Byte.valueOf(b1);
System.out.println(b3);

// 2、jdk1.5的特性:直接赋值
Byte b4 = b1;
System.out.println(b4);

// 由Byte ----->byte 办法有jdk1.4和jdk1.5的特性的办法,跟以上一样。
}
}

18. Object类;
e、 了解Object类;
Object是在java.lang.Object,它是所有类层次结构的跟类,也就是超类。
A、 Object中的toString与equals方法;
举一个例子;
请看一下代码:
package day08.object;

/**
* 测试toString和equals方法
*
* @author zouguoliang
*
*/
public class ObjectManager {
public static void main(String[] args) {
// 测试toString方法
Object obj = new Object();
System.out.println(obj.toString());
System.out.println(obj);
// 打印对象出来,系统默认调用了Object当中的toString方法。

// 测试equals方法
Object obj2 = new Object();
Object obj3 = obj;
System.out.println(obj.equals(obj2));
System.out.println(obj.equals(obj3));

// 总结:
/**
* Object类型的引用如何判断地址是否相等 1、通过equals方法进行判断 2、通过==来判断
*/
System.out.println(obj == obj2);
System.out.println(obj == obj3);
}
}
总结:I、当你打印对象的时候,系统会默认调用toString方法。
II、当object类型判断地址是否相等的时候,一是通过equals方法进行判断,二通过==号来判断。
19. String类;
f、 equals方法:
比较的是2个对象的所指向的内容(栈的内容)是否相等。
g、 ==:
比较的是地址。
请看以下一个综合的例子;
package day08.string;

/**
* 通过String内存机制来阐述equals方法==的运用
*
* @author zouguoliang
*
*/
public class StringManager {
public static void main(String[] args) {
// 定义String类型的引用可以有2种方式
/**
* 1、直接赋值 2、调用String类的构造方法
*/
String str = "kende";
String str2 = new String("kende");
String str3 = new String("kende");
String str4 = "kende";
String str5 = str2;
String str6 = "jason";
String str7 = new String("jason");
// 以上2种方式是不同新建String类型引用的方式。通过一幅图来说明他们之间的区别。
// 也就是String的内存机制
/**
* 1、直接赋值:直接从对象池中获取栈的内容,成为一个引用。 2、调用构造方法,构造方法中需要参数从对象池中获取参数。最终成为一个引用
*
*/

// 判断2个字符串的引用的地址是否相等。只能通过==进行判断
/**
* 1、两个字符串的引用都是通过直接赋值的方式 总结:地址是否相等:只需要看内容是否相等,内容相等,则地址相等。
*/
System.out.println(str == str4);// kende--->kende
System.out.println(str == str6);// kende--->jason

/**
* 2、两个字符串的引用都是通过调用构造方法的方式
* 总结:只要新建了另外一片空间,那么地址肯定不相等,除非直接将另外一个实例赋值过来用那就相等.
*/
System.out.println(str2 == str7); // new String("kende"); new
// String("jason");
System.out.println(str2 == str3);
System.out.println(str2 == str5);

/**
* 3、一个引用是通过直接赋值,一个引用是通过调用构造方法。 总结:获取引用的方式是不一样,所以地址肯定不相等。
*/
System.out.println(str == str2);

// 总结:当判断2个引用的地址是否相等的时候
// 只有2个引用都是直接赋值的时候,才有可能为true(内容相等的时候)和将另外一个实例直接赋值过来也是为true
// 其他情况全部为false.

// 以上是判断地址

/*************************************************/
/**
* 判断栈里边的内容是否相等,通过String类下的equals方法
* 总结:只需要看对象池的内容或者是保存在栈的内容是否相等。如果相等,则调用equals方法之后就为true的结果。
*
*/
System.out.println(str.equals(str2));
System.out.println(str.equals(str6));
System.out.println(str.equals(str7));
}
}
通过以上的代码得出总结。
1 定义String类型的引用可以有2种方式
2 通过一幅图来说明String引用方式(内存机制)。

3 通过以上的图可以看出,String类的引用由有两种方式;第一是直接赋值;第二是调用String类的构造方法。
4 直接赋值是从对象池中获得栈的引用,成为一个引用。
5 而调用构造方法是构造方法参数从对象池或取参数,最终成为一个引用。
6 当你判断字符串地址是否相等的时候只能用“==”号来比较。
I、 若比较字符串是直接通用引用赋值,只要他们的内容一样,地址值就一样。
II、 若比较字符串是通过构造方法赋值,则他们的地址值就不一样,除非直接将另外一个实例赋值过来用那就相等。
III、 若比较字符串一个是通过直接赋值,一个是通过构造方法,则他们的地址值就不一样。
IV、 只需要看对象池的内容或者是保存在栈的内容是否相等。如果相等,则调用equals方法之后就为true的结果。
20. 那让我们再看看String类的其他方法;
代码:
package day09.string;

public class StringManager {

public static void main(String[] args) {
// 将制定字符串中的制定的字符切去出来。
String value = "kende";
// 将'd'切出来
char chars = value.charAt(3);
System.out.println(chars);

String value2 = "经常去游泳!";
String value3 = value.concat(value2);
System.out.println(value3);

// 测试contains方法:value字符串中包含了de这个子字符串
CharSequence charsSeq = new String("ue");
boolean result = value.contains(charsSeq);
System.out.println(result);

// 测试endsWith和startsWith
String sql = "Select * from user_list";
System.out.println(sql.endsWith("user_list"));
System.out.println(sql.toLowerCase().startsWith("select"));

// 将 /192.168.22.8中前面的/截取掉:可以是split方法进行
String address = "/192.168.22.8";
String[] addresses = address.split("/");
System.out.println("地址为:" + addresses[1]);

String addressAndPort = "192.168.22.8=8888";
// 将字符串中的ip地址(String类型)和端口号8888(int类型)分离
String[] addressAndPorts = addressAndPort.split("=");

String address2 = addressAndPorts[0];
int port = Integer.parseInt(addressAndPorts[1]);
System.out.println(address2);
System.out.println(port);

String value4 = "kende";
System.out.println(value4);
}
}

21. final;
I、可以修饰类名:代表这是最终的类,没有子类(太监类)。
II、可以修饰属性名称:代表是一个常量。
III、可以修饰方法:代表这个方法不能被子类重写。
就让我们看一下代码:
package day08.finalmanager;
/**
* 定义个FinalSub子类
* @author zouguoliang
*
*/
public class FinalSub extends FinalSuper{
// public final void test2(){
//
// }
}

package day08.finalmanager;
/**
* 1、final修饰类名,表示这个类没有子类。
*
* @author ITGZ
*
*/
public class FinalSuper {
private final String SEX = "男";

public void test(){
/**
* 2、final修饰属性的时候,是一个常量,值不能被修改。
*/
// SEX = "男";
}

/**
* 3、final修饰方法,不能被子类改写。
*/
public final void test2(){

}
}
通过以上代码可以总结出:
I、 当被final修饰的类,表示这个类没有子类。
II、 当final修饰属性的时候,它就表示为一个常量,不能被改写其内容。
III、 当final修饰方法的时候,它就不能被子类改写(重写)。
22. this;
I、可以调用当前类的属性。
II、可以表示当前类的引用。
III、可以表示调用当前类的构造方法。
IV、可以表示调用当前类的方法。
就让我们看一下代码:
package day08.thismanager;

public class ThisManager {
private String name = "kende";
private int age = 30;

public ThisManager() {

}

public ThisManager(String name) {
this.name = name;
}

public ThisManager(String name, int age) {
// this.name = name
// 可以用this当前类的有1个字符串参数的构造方法
// this.name = name;
// 2、表示调用当前类的构造方法
// 总结:当通过this调用当前类的构造方法的时候
// 必须放在构造方法的第一行的位置。
this(name);
// 1、表示调用当前类的属性(当参数名称和属性名称一致的时候,为了区分是属性,用this来调用当前类的属性)
this.age = age;

}

public void test(ThisManager manager) {
// this(name);
System.out.println(manager);
}

public void test2() {
// 3、前面的this代表调用当前类的方法
// 4、后面的this代表当前类的引用。
// this.test(new ThisManager());
this.test(this);
}

public static void main(String[] args) {
// 调用test方法
ThisManager manager = new ThisManager();
// this关键字不能使用在静态的方法或者静态的代码块中。
// manager.test(this);
manager.test(manager);
}
}
通过以上代码可以总结出如下结论:
I、 可以表示当全类的有一个参数的构造方法
II、 表示当前类的构造方法,当使用this调用当前类的构造方法的时候必须把此方法放在构造方法第一行的位置,否则就报错。
III、 This可以表示当前类的方法,也可以表示当前类引用。
IV、 This关键字不能使用静态代码块中(用static修饰的方法或者类中)。
23. super;
I、可以调用父类的属性。
II、可以调用父类的构造方法。
III、可以调用父类的方法。
就让我们看一下代码:
package day08.supermanager;

/**
* 定义一个Super父类;
*
* @author zouguoliang
*
*/
public class Super {
public String name = "super";

public Super() {

}

public Super(String name) {
this.name = name;
}

public void testSuper() {

}

}

package day08.supermanager;

/**
* 定义一个Sub子类;
*
* @author zouguoliang
*
*/
public class Sub extends Super {
private String name = "sub";

public Sub() {
// new Sub().name = "kende";
// 1、表示调用父类的属性
super.name = "kende";
}

public Sub(String name) {
// 2、调用父类的构造方法:也只能放在构造方法的第一行的位置。
super(name);
System.out.println();
}

public void testSub() {
// 3、调用父类的自定义方法
// new Sub().testSuper();
super.testSuper();
}

public static void main(String[] args) {
// super表示对象,不能使用在静态的代码块中。
// System.out.println(super.name);
}
}
通过以上代码可以总结如下:
I、 通过super可以调用父类的属性。
II、 调用父类的构造方法时,只能放在构造方法的第一行。
III、 通过super可以调用父类的自定义方法。
IV、 同样跟this关键字一样不能讲起写在静态代码块中的。
9、 Day09;
24. Static的运用;
Static可以修饰类名,但是类名必须是内部类哦(内部类可以分为静态内部类以及非静态内部类)。
Static可以修饰属性。
Static可以修饰方法。
Static可以修饰代码块。
25. 类的加载(一个类);
在一个类中如果有静态代码块,非静态代码块,构造方法,这3快。其加载顺序为:
在看起加载顺序前,我们说说几组概念:
h、 类的级别;
XII、 类
XIII、 静态的属性和静态方法
XIV、 静态代码块
XV、 父类
a、 对象的级别;
XVI、 实例化的对象
XVII、 非静态的属性和给静态的方法
XVIII、 构造方法
XIX、 非静态的代码块
XX、 this和super
XXI、 子类
a、 优先级;
XXII、 类是先产生的,而后才产生对象,所以类的优先级高于对象的优先级。所以在类级别和对象级别度存在的情况下,会先加载类的级别。
XXIII、 有以上可以看出,当调用构造方法(加载对象时)的时候,会先加载静态代码块,并且非静态的代码块的优先级高于构造方法。所以在加载构造方法的时候,最先加载的是静态代码块,其次是非静态代码块,最后才是构造方法。
注意:在主方法中,即便是没有调用构造方法,也会执行静态的代码块中的内容。
XXIV、 通过以上可以引出一下问题;
a、 如果同队对象的方式(通过引用)去访问静态方法:
其加载顺序:静态代码块 =====非静态代码块=====
构造方法
b、 如果通过类名或者直接访问静态方法;
其加载顺序:只加载静态的代码块。为何?(可以用父类和子类来理解,在父类中通过父类的引用去调用子类的属性和方法,是不行的,但是在子类中通过子类的引用去调用父类的属性和方法是可以的,为什么??(因为父类的优先级高于子类,不能在父类中调用子类的属性和方法,同理,通过类的级别访问的静态的访问,那么只加载类的级别的代码块,对象级别的都不加载的))。
注意:在静态的代码块或者静态的方法里边要是去访问更低级的属性和方法(非静态的属性和方法),不能直接访问,如果要访问,必须通过引用来访问。
26. 类的加载(两个类);
在两个类中如果有静态代码块,非静态代码块,构造方法,这3块。其加载顺序为:
c、 其顺序;
I、 父类的静态代码块,子类的静态代码块。
II、 父类的非静态代码块,父类的构造方法。
III、 子类的非静态代码块,子类的构造方法。

d、 其顺序的理解;
XXV、 类级别的优先级高于对象,所以先加载类的级别。
XXVI、 父类的优先级高于子类,所以先加载父类,后加载子类。
27. 总结:类的加载到底用在哪里?
比如可以将通用性很强或者多个方法都需要调用的代码都放在静态代码块中或者非静态代码快或者构造方法中去的任何的一个地方。
注意:如果通过类名去访问静态的方法,那只能将这段代码放在静态的代码块中。
10、 Day10;
28. 异常类;
a、 异常类不是错误;
错误一旦提交到jvm中去执行是不可以修复的,但是异常是可以解决的。
b、 异常是java的类中的医生;
异常类出现的异常可以解决,可以通过自己解决以及别人来解决的。
c、 异常的种类;
i. 非运行时候的异常(是还没有执行的时候就已经有异常信息的出现)
ii. 运行时候的异常(在执行的时候才出现的异常信息)
d、 举一个例子;
代码:
package day10.excepion;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 非运行时候的异常信息:本身在程序代码中有报错的。
* 处理办法:抛出去
* @author zouguoliang
*
*/
public class ExceptionManager {

public static BufferedReader getBuffer(){
return new BufferedReader(new InputStreamReader(System.in));
}

public static void main(String[] args) throws IOException {
BufferedReader br = getBuffer();
while(true){
System.out.println("请输入数据:");
//br下的readLine方法本身自己没有处理异常,而是抛出去的异常,这个异常信息就转嫁给了主方法。
/**
* 主方法可以解决这个异常,有2种办法:
* 1、自己解决:try...catch------>将相关有异常信息的代码放在try中。如果有异常信息就会执行catch代码块。
* 2、抛出去给别人(jvm)处理:在声明方法的后边加上throws +异常类。
*/
String data = br.readLine();
System.out.println(data);
if(data.equals("close")){
System.out.println("已经跳出!");
break;
}
}
}
}
e、 解决异常;
程序代码中本身有报错的这类异常可以通过try…catch,也可以通过抛出去解决。 但是如果程序代码中没有报错,但是执行过程中出错的这类异常只能通过try…catch
f、 异常信息的分类;
B、 主动方法抛出;
通常来说会自定义一个异常类,为何需要自定义异常类?因为在api中找不到自己想要的异常类,所以自己定义一个异常类,自定义的这个类必须要继承RuntimeException,接下来在方法体中通过thow关键字将自定义异常类的引用抛出去。
C、 预定义方法抛出;
Api中Exception类或者他的子类在声明方法的时候通过throws Exception或者Exception的子类。
g、 方法抛出的层次问题;
当有一个方法 A 他有异常信息,但是自己没有通过try…catch的方法处理这个异常。现在有一个B 方法要调用A 方法,现在A 方法的异常就转嫁给了B 方法,但是B 方法也没有进行处理。
主方法去调用没有处理过异常信息的B 方法。主方法也没有进行处理,但是主方法是跟jvm挂钩的,jvm到底能不能处理这个异常信息,那就要看这个异常信息的种类了。
D、 如果是运行时候的异常;
比如RuntimeException(最经常见的NullPointerException)这种异常,jvm是没有办法解决的,这个时候程序代码就会在有异常信息的代码处终止程序了,然而后面的额代码也就没有执行了。
E、 如果是非运行时的异常;
这是异常是代码中本身就报错的,即使方法中都没有处理自己的异常,最后转嫁给了jvm,jvm同样可以处理这类异常。
29. 集合;
h、 概念;
集合可以看成是特殊的数组,可以比数组拥有更多的功能,可以进行增删改查等操作。
集合:所有集合的超级接口教Iterable,子接口为Collection。
Collection与Collections的区别:前者是集合的接口,后者是一个工具类。
i、 集合的接口;
集合的接口Collection常见的子接口有:List,Set,Map不是Collection下的子接口,他是键值对存在的。一个元素中两个参数。
F、 List常见的实现类有;
ArrayList,LinkedList,Vector,接下来为其一一解释其操作。
G、 List下的实现类ArrayList的操作;
XXVII、 添加元素
XXVIII、 查询元素
XXIX、 删除元素
XXX、 修改元素
先看看ArrayList的构造方法;

再看看其主要方法;


那么通过一个例子来说明一下;
package day10.list;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
* ArrayList常用的操作:
* List的特点:
* 1、查询元素的顺序是按照添加元素的顺序查询出来。
* 2、会将重复的元素打印出来(或者说没有排重功能)
* 3、查询有2种方式,可以通过下标查询,也可以通过迭代查询。
* 4、List是可以传入值为null的元素。
* 5、ArrayList是不同步的,也就是没有加上synchronized,也就是采用多线程的效果,速度快 反之数据不够安全。
*
*
* @author zouguoliang
*
*/
public class ArrayListManager {

public static void main(String[] args) {
List list = new ArrayList();
// 添加元素
list.add("kende");
list.add("kende");
list.add(1);
list.add(new Date());
list.add(20.0);
list.add(null);

// 查询元素:
/**
* List查询元素有2种办法:
* 1、下标查询(普通的for循环)
* 2、迭代器的查询(返回一个Iterator接口)
*/
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}

System.out.println("通过迭代查询的效果为:");
Iterator it = list.iterator();
while (it.hasNext()) {
Object value = it.next();
System.out.println(value);
}

/**
* 删除功能:可以传入删除元素的索引,也可以传入具体的元素值。
*/
System.out.println("删除的元素是:" + list.remove(2));

/**
* 修改功能:
*/
list.set(3, 50.0);
System.out.println("修改20.0之后的效果为:");
Iterator it2 = list.iterator();
while (it2.hasNext()) {
Object value = it2.next();
System.out.println(value);
}
}
}
通过以上例子可以总结出List的特点;
I、 查询元素是按照添加元素的顺序查询出来的
II、 没有排除重复元素的功能,会将重复的打印出来
III、 其查询方式有两种:可以通过下标,也可以通过迭代来查询
IV、 List是可以传染null
V、 ArrayList是不同步的,也就是没有加上synchronizated,也就是采用了多线程,速度快,但是不安全的
H、 List下的实现类LinkedList的操作;
实现的机制是个Stack实现的机制类似,是先进后出的原则,通常来说有这么几个方法可以实现
I、 添加元素(push)
II、 查询元素(peek)
III、 删除元素(pop)
IV、 修改元素
先看看其构造方法:

在看看其自定义方法;


还是通过代码来说明更好:
代码:
package day10.list;

import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Stack;
/**
* 1、LinkedList实现的机制是链表的机制,跟Stack实现的原理是类似的,提供了相关的方法。
* 2、LinkedList除了具备ArrayList相关的功能之外,还具备Stack中的相关的功能(push, peek, pop)
* 3、也是不同步的,没有加synchronized,其实就是一个多线程。速度快,不安全的。
* 4、也可以添加null值的元素。
*
* 跟Vector的相同点和不同点:
* 相同:都跟Stack实现的机制类似
* 不同的地方:Vector是同步的,加了synchronized来修饰方法,也就是单线程,速度慢
* 但是安全性能高。
* @author ITGZ
*
*/
public class LinkedListManager extends Stack{

private LinkedList list = new LinkedList();

/**
* 查询的方法
*/
@Override
public synchronized Object peek() {
Iterator it = list.iterator();
Object value = null;
while(it.hasNext()){
value = it.next();
System.out.println(value);
}
return value;
}

/**
* 删除的方法
*/
@Override
public synchronized Object pop() {
Object value = list.removeLast();
return value;
}

/**
* 添加的方法
*/
@Override
public Object push(Object obj) {
list.addLast(obj);
return obj;
}

public static void main(String[] args) {
LinkedListManager manager = new LinkedListManager();
//添加元素
manager.push("kende");
manager.push(5);
manager.push(new Date());
//查询元素
manager.peek();

System.out.println("删除之后的结果为:");
//删除元素
manager.pop();
manager.peek();
}
}
通过以上代码可以总结出:
IX、 LinkedList实现的机制是链表的机制,跟Stack实现的原理是一样的,提供了相关的方法
X、 LinkedList除了具备ArrayList的相关功能之外,还具备Stack中的相关功能(push、peek、pop)
XI、 LinkedList也是不同步的,没有加synchronizated,也就是说是一个多线程来的,速度快,但不安全。
XII、 也可往里添加null
跟Vector的相同之处和不同之处:
相同点:都跟Stack实现的机制相同。
不同点:Vector是同步的,加了synchronizated来修饰方法,也就是单线程,速度慢,是安全的。
A、 Set常见的实现类;
I、 HashSet
先看看其中的构造方法;

再看看其自定义方法;

用代码来说明一下:
package day10.set;

import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
* HashSet的特点:
* 1、查询只有迭代查询
* 2、具有排重功能。
* 3、可以添加任何引用类型的值,也可以添加null值的元素
* 4、查询元素的顺序不能保证每次都恒久不变,跟HashMap是一样的。
* 5、不同步的,不安全,多线程,速度快。
*
* @author Administrator
*
*/
public class HashSetManager {

public static void main(String[] args) {
// 添加元素
Set set = new HashSet();
Date d = new Date();
set.add("kende");
set.add(1);
set.add(d);
set.add("kende");
set.add(null);
// 查询元素:
/**
* 只有通过迭代查询。
*/
Iterator it = set.iterator();
while (it.hasNext()) {
Object value = it.next();
System.out.println(value);
}

// 删除:将1元素删除
set.remove(1);
System.out.println("删除之后的效果为:");
Iterator it2 = set.iterator();
while (it2.hasNext()) {
Object value = it2.next();
System.out.println(value);
}

// 修改功能:
// 没有直接修改功能的方法,但是可以先删除,然后再添加
// 将Date元素修改为”jason“
set.remove(d);
set.add("jason");
System.out.println("修改之后的效果为:");
Iterator it3 = set.iterator();
while (it3.hasNext()) {
Object value = it3.next();
System.out.println(value);
}
}
}
总结:
HashSet的特点
2、 查询只能是迭代查询
3、 具有排重功能
4、 可以添加任何类型的数据类型,也可是null
5、 查询出来的元素的顺序不能保证都是恒久不变的,跟HashMap是一样的

II、 TreeSet
先看看其中的构造方法;

再看看其自定义方法;


用代码来说明一下:
package day10.set;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

/**
* TreeSet的特点:
* 1、查询出来的元素有顺序的,能够对自然元素进行排序。
* 2、只能添加同种类型的元素。而且不能添加null值的元素
* 3、跟HashSet一样,也具有排重功能。
* 4、安全性能跟HashSet是一样的。也是不安全的,不同步的。
*
* @author ITGZ
*
*/
public class TreeSetManager {

public static void main(String[] args) {
Set set = new TreeSet();
// 添加元素
set.add("kende");
set.add("jason");
set.add("apple");
set.add("apple");
// set.add(null);

// 查询:只能通过迭代
Iterator it = set.iterator();
while (it.hasNext()) {
Object value = it.next();
System.out.println(value);
}
}
}
再看看这个例子,通过实例化出来的对象的排序
package day10.set;
/**
* 定义一个Student类
* @author Administrator
*
*/

public class Student implements Comparable {
private String name;
private int age;

public Student(String name, int age) {
this.name = name;
this.age = age;
}

/**
* Comparable比较器的比较的方法。
*/
public int compareTo(Object obj) {
if (obj != null) {
if (obj instanceof Student) {
Student stu = (Student) obj;
return (this.age - stu.age);
} else {
return 0;
}
} else {
// 表示不排序
return 0;
}
}

@Override
public String toString() {
return name + "-" + Integer.valueOf(age).toString();
}
}

package day10.set;

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

/**
* TreeSet的特点:
* 1、查询出来的元素有顺序的,能够对自然元素进行排序。
* 2、只能添加同种类型的元素。而且不能添加null值的元素
* 3、跟HashSet一样,也具有排重功能。
* 4、安全性能跟HashSet是一样的。也是不安全的,不同步的。
* 5、可以对自然元素进行排序,也可以对自定义的对象进行整体排序
* 但是前提自定义的对象必须实现Comparable比较器的接口,同时实现compareTo方法
* 要能够对自定义的对象进行排序????
*
* @author ITGZ
*
*/
public class TreeSetManager2 {
public static void main(String[] args) {
Set set = new TreeSet();
Student stu1 = new Student("kende", 30);
Student stu2 = new Student("jason", 15);
Student stu3 = new Student("meten", 40);
Student stu4 = new Student("janet", 20);
// 添加元素
set.add(stu1);
set.add(stu2);
set.add(stu3);
set.add(stu4);
// set.add(null);

// 查询:只能通过迭代
Iterator it = set.iterator();
while (it.hasNext()) {
Object value = it.next();
System.out.println(value);
}
}
}

总结:TreeSet的特点
1、 查询出来的元素是有顺序的,可以对自然数进行排序
2、 只能添加同种类型的元素,不能添加null
3、 跟HashSet一样,具有排序功能
4、 跟HashSet一样不安全的,不同步的
5、 可以对自然元素进行排序,也可以对自定义的对象进行整体排序但是前提自定义的对象必须实现Comparable比较器的接口,同时实现compareTo方法要能够对自定义的对象进行排序
A、 Map常见的实现类;
I、 HashMap
先看看其中的构造方法;

再看看其自定义方法;

用代码来说明一下:
package day10.map;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import day10.set.Student;

/**
* map是健值对的,key,value, key----value是绑定起来的,只要知道key,也就是知道了value
* 所以现在如果要查询,只要先查询key就可以了。
*
* HashMap的特点:
* 1、健值对
* 2、查询元素的顺序的特点跟HashSet一样,都是不能保证顺序恒久不变。证明没有排序功能
* 3、可以添加任何类型的元素进来,甚至是null也可以。同时key和value都是可以是不同类型。
*
* @author ITGZ
*
*/
public class HashMapManager {

public static void main(String[] args) {
Map map = new HashMap();
// 添加元素
map.put(1, "kende");
map.put(2, new Date());
map.put("3", "jason");
map.put(4, new Student("meten", 30));
map.put(null, null);

// 查询元素
/**
* 流程:首先将key保存在Set接口里边 然后通过Set接口中的迭代查询将key查询出来。 最后再通过key,或者相对应的value
*/
Set keys = map.keySet();
Iterator it = keys.iterator();
while (it.hasNext()) {
Object key = it.next();
Object value = map.get(key);
System.out.println(key + "-" + value);
}

// 删除remove
// 修改put
map.put(1, "janet");
System.out.println();
Set keys2 = map.keySet();
Iterator it2 = keys2.iterator();
while (it2.hasNext()) {
Object key = it2.next();
Object value = map.get(key);
System.out.println(key + "-" + value);
}
}
}
再来看看一个用对象的例子
package day10.map;

public class Student implements Comparable {
private String name;
private int age;

public Student(String name, int age) {
this.name = name;
this.age = age;
}

/**
* Comparable比较器的比较的方法。
*/
public int compareTo(Object obj) {
if (obj != null) {
if (obj instanceof Student) {
Student stu = (Student) obj;
return (this.age - stu.age);
} else {
return 0;
}
} else {
// 表示不排序
return 0;
}
}

@Override
public String toString() {
return name + "-" + Integer.valueOf(age).toString();
}
}

package day10.map;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import day10.set.Student;
/**
* map是健值对的,key,value,
* key----value是绑定起来的,只要知道key,也就是知道了value
* 所以现在如果要查询,只要先查询key就可以了。
* TreeMap的特点:
* 1、健值对
* 2、查询元素的顺序的特点跟TreeSet一样,能够对自然元素(key)进行排序,
* 3、key必须添加同种类型的元素进来,而且key不能为null.
* @author ITGZ
*
*/
public class TreeMapManager2 {
public static void main(String[] args) {
Map map = new TreeMap();
Student stu1 = new Student("kende", 30);
Student stu2 = new Student("jason", 15);
Student stu3 = new Student("meten", 40);
Student stu4 = new Student("janet", 20);
//添加元素
map.put(stu1, "kende");
map.put(stu2, new Date());
map.put(stu3, null);
map.put(stu4, new Student("meten", 30));
// map.put(null, null);

//查询元素
/**
* 流程:首先将key保存在Set接口里边
* 然后通过Set接口中的迭代查询将key查询出来。
* 最后再通过key,或者相对应的value
*/
Set keys = map.keySet();
Iterator it = keys.iterator();
while(it.hasNext()){
Object key = it.next();
Object value = map.get(key);
System.out.println(key + "-" + value);
}
//删除remove

//修改put
// map.put(1, "janet");
// System.out.println();
// Set keys2 = map.keySet();
// Iterator it2 = keys2.iterator();
// while(it2.hasNext()){
// Object key = it2.next();
// Object value = map.get(key);
// System.out.println(key + "-" + value);
// }
}
}

总结:
HashMap的特点
XIII、 HashMap是以键值对的形式存在的
XIV、 查询出来的元素的顺序的特点跟HashSet一样,都是不能保证顺序的恒久不变,如此证明HashMap是没有排序的功能的
XV、 HashMap可以添加任意的类型的数据,甚至null。
XVI、 在添加元素的时候,其key和value是可以不同类型的元素都行。
II、 TreeMap
先看看其中的构造方法;

再看看其自定义方法;


用代码来说明一下:
package day10.map;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import day10.set.Student;

/**
* map是健值对的,key,value, key----value是绑定起来的,只要知道key,也就是知道了value
* 所以现在如果要查询,只要先查询key就可以了。
*
* TreeMap的特点:
* 1、健值对
* 2、查询元素的顺序的特点跟TreeSet一样,能够对自然元素(key)进行排序,
* 3、key必须添加同种类型的元素进来,而且key不能为null.
*
* @author zouguoliang
*
*/
public class TreeMapManager2 {

public static void main(String[] args) {
Map map = new TreeMap();
Student stu1 = new Student("kende", 30);
Student stu2 = new Student("jason", 15);
Student stu3 = new Student("meten", 40);
Student stu4 = new Student("janet", 20);
// 添加元素
map.put(stu1, "kende");
map.put(stu2, new Date());
map.put(stu3, null);
map.put(stu4, new Student("meten", 30));
// map.put(null, null);

// 查询元素
/**
* 流程:首先将key保存在Set接口里边 然后通过Set接口中的迭代查询将key查询出来。 最后再通过key,或者相对应的value
*/
Set keys = map.keySet();
Iterator it = keys.iterator();
while (it.hasNext()) {
Object key = it.next();
Object value = map.get(key);
System.out.println(key + "-" + value);
}

// 删除remove

// 修改put
// map.put(1, "janet");
// System.out.println();
// Set keys2 = map.keySet();
// Iterator it2 = keys2.iterator();
// while(it2.hasNext()){
// Object key = it2.next();
// Object value = map.get(key);
// System.out.println(key + "-" + value);
// }
}
}
总结:TreeMap的特点
I、 TreeMap也是通过键值对存在的
II、 查询出来的元素的顺序跟TreeSet一样,能够对自然元素(key)进行排序
III、 Key中的元素必须是同种类型,而且不能为null
A、 通过以上的Set与Map集合可以总结出;
B、 Hash系列的Set和Hash系列的Map是类似的,都不能保证输出的顺序是恒久不变的,也就是说没有排序功能的
C、 Tree系列的Set和Map都是能够对自己的自定义的对象进行排序(是要通过实现compareable接口)和自然元素进行排序。
11、 Day11;
30. 对集合的总结:List、Set、Map;
a、 从查询的角度来看;
XXXI、 List:可以通过下标查询和迭代查询
XXXII、 Set和Map都是通过迭代查询
a、 从查询出来的元素的顺序来看;
XXXIII、 List:是没有排序功能的,查询出来的顺序是根据添加进来的顺序,可以添加任何类型的元素进来,甚至null都可以的。
XXXIV、 Hash系列的Set和Hash系列的Map:都是没有排序的,可以添加任何类型的数据,甚至null。
XXXV、 Tree系列的Set和Tree系列的Map:是有排序的功能,是能够对自定义的元素及自定义的对象进行整体排序(但是要实现compareable比较器接口,同时改写compareTo方法,同时还要重写Object中的toString方法)。
a、 从排重功能来看:
XXXVI、 List:是没有排重功能的吗,能够重写重复的元素。
XXXVII、 Set:有排重的功能,也就说可以将重复的元素覆盖掉的。
XXXVIII、 Map:有排重的功能,也就说会将重复的Key的元素覆盖掉。
a、 从线程是否安全的角度来看;
XXXIX、 List:只有Vector是安全的
XL、 Set:线程不安全
XLI、 Map:TreeMap是线程不安全的
XLII、 HashMap和HashTable他们最根本的区别是:前者是不安全的,Key可以为Null,但是后者是线程安全的,而且key不可以为Null。
a、 练习题;
比如现在几个国家,比如俄罗斯(1200W平方公里) ,加拿大(1700W平方公里),中国(960W平方公里),美国(930W平方公里),巴西(770W平方公里)可以利用2种办法对以上国家的领土面积进行排序。
package mySelf;
public class Area implements Comparable {
private String nationName;
private int nationArea;

public Area(String nationName, int nationArea) {
this.nationName = nationName;
this.nationArea = nationArea;
}

@Override
public int compareTo(Object obj) {
if (obj != null) {
if (obj instanceof Area) {
Area area = (Area) obj;
return (this.nationArea - area.nationArea);
} else {
return 0;
}
} else {
return 0;
}
}

@Override
public String toString() {
return nationName + "===" + nationArea+"万平方公里";
}
}

package mySelf;

import java.util.Iterator;
import java.util.TreeSet;

/**
* 比如现在几个国家,比如俄罗斯(1200W平方公里), 加拿大(1700W平方公里),中国(960W平方公里),
* 美国(930W平方公里),巴西(770W平方公里) 可以利用2种办法对以上国家的领土面积进行排序。
*
* @author zouguoliang
*
*/
public class MyAreaDemo {
public static void main(String[] args) {
Area area1 = new Area("加拿大", 1100);
Area area2 = new Area("俄罗斯", 1700);
Area area3 = new Area("中国", 960);
Area area4 = new Area("巴西", 770);
Area area5 = new Area("美国", 930);
TreeSet treeSet = new TreeSet();
treeSet.add(area1);
treeSet.add(area2);
treeSet.add(area3);
treeSet.add(area4);
treeSet.add(area5);
// 只能通过迭代来显示数据的;
Iterator iterator = treeSet.iterator();
while (iterator.hasNext()) {
Object values = iterator.next();
System.out.println(values);
}
}
}
还有其他的方法可以做出来。
12、 Day12;
31. 文件对象;
b、 了解文件对象:File;
文件和目录路径名的抽象表示形式。用户界面和操作系统使用与系统相关的路径名字符串 来命名文件和目录。此类呈现分层路径名的一个抽象的、与系统无关的视图。抽象路径名 有两个组件: 一个可选的与系统有关的前缀 字符串,比如盘符,"/" 表示 UNIX 中的根目录,"\\\\" 表示icrosoft Windows UNC 路径名。零个或更多字符串名称 的序列。抽象路径名中的第一个名称是目录名,对于 Microsoft Windows UNC 路径名则是主机名。抽象路径名中第一个名称之后的每个名称表示一个目录;最后一个名称既可以表示目录,也可以表示文件。空 抽象路径名没有前缀和名称序列。
File可以操作目录(文件夹),也可以操作文件(带有后缀名)。
请让我们看看File的构造方法

再看看其自定义的方法;



c、 如何操作文件或文件夹;
D、 创建文件即及文件夹;
通过以下代码来说明;
package mySelf;

import java.io.File;
import java.io.IOException;

/**
* 这是一个创建文件或者文件夹的一个类;
*
* @author zouguoliang
*
*/
public class CreateFile {
// 定义一个可以创建文件的方法;
public void createFiles(String filePath) throws IOException {
File file = new File(filePath);
Boolean createFiel = file.createNewFile();
if (file.exists()) {
System.out.println("文件已经存在");
} else {
System.out.println("恭喜你,文件" + file.getName() + "创建成功");
}
}

// 定义一个可以创建文件夹的方法;
public void createFolder(String folderPath) {
File folder = new File(folderPath);
Boolean createFolder = folder.mkdir();
if (folder.exists()) {
System.out.println("文件夹已经存在");
} else {
System.out.println("恭喜你,文件夹" + folder.getName() + "创建成功");
}
}

public static void main(String[] args) throws IOException {
CreateFile createFile = new CreateFile();
createFile.createFiles("src/mySelf/zgl.txt");// 创建文件
createFile.createFolder("src/mySelf/zgl");// 创建文件夹
}
}
E、 删除文件及文件夹;
package mySelf;

import java.io.File;
import java.io.IOException;

/**
* 这是一个创建文件或者文件夹的一个类;
*
* @author zouguoliang
*
*/
public class CreateFile {
// 定义一个可以创建文件的方法;
public void createFiles(String filePath) throws IOException {
File file = new File(filePath);
Boolean createFiel = file.createNewFile();
if (file.exists()) {
System.out.println("文件已经存在");
} else {
System.out.println("恭喜你,文件" + file.getName() + "创建成功");
}
}

// 定义一个可以删除文件的方法;
public void deleteFile(String filePath) throws IOException {
File file = new File(filePath);
Boolean deleteFiel = file.delete();
System.out.println("恭喜你,文件删除成功");
}

// 定义一个可以创建文件夹的方法;
public void createFolder(String folderPath) {
File folder = new File(folderPath);
Boolean createFolder = folder.mkdir();
if (folder.exists()) {
System.out.println("文件夹已经存在");
} else {
System.out.println("恭喜你,文件夹" + folder.getName() + "创建成功");
}
}

// 定义一个可以删除文件夹的方法;
public void deleteFolder(String folderPath) {
File folder = new File(folderPath);
Boolean deleteFolder = folder.delete();
System.out.println("恭喜你,文件夹成功");
}

public static void main(String[] args) throws IOException {
CreateFile createFile = new CreateFile();
createFile.createFiles("src/mySelf/zgl.txt");// 创建文件
createFile.deleteFile("src/mySelf/zgl.txt");// 删除文件
createFile.createFolder("src/mySelf/zgl");// 创建文件夹
createFile.deleteFolder("src/mySelf/zgl");// 删除文件夹
}
}
F、 获取文件及文件夹的名称;
package mySelf;

import java.io.File;
import java.io.IOException;

/**
* 这是一个创建文件或者文件夹的一个类;
*
* @author zouguoliang
*
*/
public class CreateFile {
// 定义一个可以创建文件的方法;
public void createFiles(String filePath) throws IOException {
File file = new File(filePath);
Boolean createFiel = file.createNewFile();
if (file.exists()) {
System.out.println("文件已经存在");
} else {
System.out.println("恭喜你,文件" + file.getName() + "创建成功");
}
}

// 定义一个可以删除文件的方法;
public void deleteFile(String filePath) throws IOException {
File file = new File(filePath);
Boolean deleteFiel = file.delete();
System.out.println("恭喜你,文件删除成功");
}

// 定义一个可以创建文件夹的方法;
public void createFolder(String folderPath) {
File folder = new File(folderPath);
Boolean createFolder = folder.mkdir();
if (folder.exists()) {
System.out.println("文件夹已经存在");
} else {
System.out.println("恭喜你,文件夹" + folder.getName() + "创建成功");
}
}

// 定义一个可以删除文件夹的方法;
public void deleteFolder(String folderPath) {
File folder = new File(folderPath);
Boolean deleteFolder = folder.delete();
System.out.println("恭喜你,文件夹成功");
}

// 定义一个可以获取文件及文件夹的方法;
public void getFileAndFolderName(String folderPath) {
File fileAndFolder = new File(folderPath);
String fileAndFolderName = fileAndFolder.getName();
System.out.println("文件名称:" + fileAndFolderName);
}

public static void main(String[] args) throws IOException {
CreateFile createFile = new CreateFile();
createFile.createFiles("src/mySelf/zgl.txt");// 创建文件
// createFile.deleteFile("src/mySelf/zgl.txt");// 删除文件
createFile.getFileAndFolderName("src/mySelf/zgl.txt");// 获取文件名字
// createFile.createFolder("src/mySelf/zgl");// 创建文件夹
// createFile.deleteFolder("src/mySelf/zgl");// 删除文件夹
}
}
G、 练习;
XVII、 将一个路径下的所有的文件和文件夹的名字都打印出来。
package day11.file;
import java.io.File;
/**
* 将一个路径下的所有的文件和文件夹的名字都打印出来。
*
* @author zouguoliang
*
*/

public class ScanFileAndDirectoryManager {

public static void scanFileAndDirectory(String path) {
File file = new File(path);
String[] curFileAndDirectoryfiles = file.list();
// 遍历path路径下的文件或者文件夹。
for (int i = 0; i < curFileAndDirectoryfiles.length; i++) {
// 获取path路径下的元素的名称(文件夹和文件的名称)
String curFileAndDirectoryfile = curFileAndDirectoryfiles[i];
// 生成新的路径:
String newPath = path + File.separator + curFileAndDirectoryfile;

// 生成新的file对象
File file2 = new File(newPath);

// 判断新的File2的对象绑定的newPath到底是文件夹的路径,还是文件的路径
if (file2.isFile()) {
System.out.println("文件的全路径名称为:" + newPath);
} else {
// 如果是文件夹,递归调用,将新的文件夹的路径传入到本方法中调用
scanFileAndDirectory(newPath);
System.out.println("文件夹的全路径名称为:" + newPath
+ "-----------------------------");
}
}
}

public static void main(String[] args) {
scanFileAndDirectory("E:/");
}
}
XVIII、 将以上路径下的指定文件格式的文件删除,比如*.txt,*.doc, *.ppt的文件删除。
package day11.file;

import java.io.File;

/**
*
将以上路径下的指定文件格式的文件删除,比如*.txt,*.doc, *.ppt的文件删除。
* @author zouguoliang
*
*/
public class DeleteFileAndDirectoryManager {

public static void scanFileAndDirectory(String path) {
File file = new File(path);
String[] curFileAndDirectoryfiles = file.list();
// 遍历path路径下的文件或者文件夹。
for (int i = 0; i < curFileAndDirectoryfiles.length; i++) {
// 获取path路径下的元素的名称(文件夹和文件的名称)
String curFileAndDirectoryfile = curFileAndDirectoryfiles[i];
// 生成新的路径:
String newPath = path + File.separator + curFileAndDirectoryfile;

// 生成新的file对象
File file2 = new File(newPath);

// 判断新的File2的对象绑定的newPath到底是文件夹的路径,还是文件的路径
if (file2.isFile()) {
if (curFileAndDirectoryfile.endsWith(".txt")
|| curFileAndDirectoryfile.endsWith(".ppt")
|| curFileAndDirectoryfile.endsWith(".doc")) {
boolean result = file2.delete();
System.out.println("删除文件的全路径名称为:" + newPath);
}

} else {
// 如果是文件夹,递归调用,将新的文件夹的路径传入到本方法中调用
scanFileAndDirectory(newPath);
}
}
}

public static void main(String[] args) {
scanFileAndDirectory("F:\\Oracle Java_20120710");
}
}
32. IO流;
d、 概念;
简称是输入输出流,用来读写数据,上传和下载数据的功能。
注意:
外接设备:比如鼠标,键盘,硬盘等等成为外界设备。是看得见的。
内存:也就是程序,是看不见的。
e、 分类;
A、 从数据的流向来分;
B、 输入流:外界流----程序 这个过程称之为是读数据的过程。
外界设备的低端流:InputStream
内存的高端流:InputStreamReader,BufferedReader
C、 输出流:程序---外接设备 这个过程称之为写数据的过程。
外界设备的低端流:OutputStream
内存的高端流:OutputStreamWriter,PrintWriter,PrintStream
D、 从数据的对象来分;
E、 高端流:所有程序中的流都称为高端流。
高端流的对象基本都带有后缀Read,Writer,比如InputStreamReader,OutputStreamWriter
F、 低端流:所有外界设备中的流度称之为低端流。
低端流的对象基本度不带有后缀名的Read,Writer,比如InputStream,OutputStream
G、 从数据的格式来分;
H、 字节流:能够处理声音和图片等二进制的数据流。
所有的低端流都是字节流。InputStream,OutputStream
I、 字符流:能够处理文本信息的流称之为字符流。
所有的高端流都是字符流。InputStreamReader,OutputStreamWriter
J、 从流的对象是否需要包装来分;
K、 原始流:InputStream或者OutputStream下的子类都是原始流,没有通过另外一个流来包装自己
L、 包装流:InputStreamReader或者OutputStreamWriter下的子类都是包装流。
f、 如何读取文本数据;
可以通过两种方式来读取文本数据
通过代码来说明1;
package day11.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
* 读文本数据:输入流对象,而且是字符流(InputStreamReader)
*
* @author zouguoliang
*/
public class ReadTextDataManager {

public static void main(String[] args) throws IOException {
File file = new File("src\\day11\\io\\a.txt");
// 建立外界设备中的输入低端流对象
InputStream is = new FileInputStream(file);
// 建立内存中的输入高端流对象
InputStreamReader isr = new InputStreamReader(is);

// 定义一个字符格式的数组。通过InputStreamReader下的read方法讲a.txt中的数据
// 包装到char格式的数组中
char[] chars = new char[1024];
while (true) {
int size = isr.read(chars);
if (-1 == size) {
// 读完了数据,跳出来。
break;
}

// 将字符格式的数组转成String类型显示出来。
String values = new String(chars, 0, size);
System.out.println(values);
}

// 关闭流的对象:
// 正常的关闭流:从流的源头开始关闭。
is.close();
isr.close();
}
}
通过代码来说明2;
package day11.io;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
* 读文本数据:输入流对象,而且是字符流(InputStreamReader)
*
* 如果想让读取数据的效率更高,可以不用像数组一样一个个字符读取,而是可以以行为单位一行行读取 那就可以使用BufferedReader。
*
* @author zouguoliang
*/
public class ReadTextDataManager3 {

public static void main(String[] args) throws IOException {
File file = new File("src\\day11\\io\\a.txt");
//建立外界设备中的输入低端流对象
InputStream is = new FileInputStream(file);
//建立内存中的输入高端流对象
InputStreamReader isr = new InputStreamReader(is);
//定义高效率读取数据的缓冲流对象
BufferedReader br = new BufferedReader(isr);
while(true){
String data = br.readLine();
if(data == null){
//读完
break;
}
System.out.println(data);
}

//关闭流的对象:
//正常的关闭流:从流的源头开始关闭。
is.close();
isr.close();
br.close();
}
}
解释1024通过代码来说明;
package day11.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
* 读文本数据:输入流对象,而且是字符流(InputStreamReader) 解析1024:
*
* @author zouguoliang
*/
public class ReadTextDataManager2 {

public static void main(String[] args) throws IOException {
File file = new File("src\\day11\\io\\a.txt");
// 建立外界设备中的输入低端流对象
InputStream is = new FileInputStream(file);
// 建立内存中的输入高端流对象
InputStreamReader isr = new InputStreamReader(is);

// 定义一个字符格式的数组。通过InputStreamReader下的read方法讲a.txt中的数据
// 包装到char格式的数组中
// 8:每次只能将8个字符装到chars中去。(包含有换行以及程序代码中换行)
char[] chars = new char[10];
while (true) {
int size = isr.read(chars);
if (-1 == size) {
// 读完了数据,跳出来。
break;
}
// 将字符格式的数组转成String类型显示出来。
String values = new String(chars, 0, size);
System.out.println(values);
}

// 关闭流的对象:
// 正常的关闭流:从流的源头开始关闭。
is.close();
isr.close();
}
}
此处可以通过debug来获取运行结果的。
自己的代码:
package day11.io;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

/**
* 读文本数据:输入流对象,而且是字符流(InputStreamReader)
*
* @author zouguoliang
*/
public class MyReadTextDataManager {
// 定义一个通过键盘输入要读的文件的路径的方法;
public static Scanner getScan() {
return new Scanner(System.in);
}

public static BufferedReader getKey() {
return new BufferedReader(new InputStreamReader(System.in));
}

// 定义一个通过字符方法一个一个来读取文本数据的方法
public static void oneRead(String filePath) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream(
new File(filePath)));
char[] chars = new char[1024];
while (true) {
int size = isr.read(chars);
if (size == -1) {
break;
}
String values = new String(chars, 0, size);
System.out.println(values);
}
isr.close();
}

// 定义一个通过行来读取数据的方法;
public static void lineRead(String filePath) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(new File(filePath))));
while (true) {
String values = br.readLine();
if (values == null) {
break;
}
System.out.println(values);
}
br.close();
}

public static void main(String[] args) throws IOException {
// BufferedReader getFilePath = getKey();
// System.out.println("请输入要读取的文件的路径");
// String getSource = getFilePath.readLine();
// lineRead(getSource);
Scanner getFilePath = getScan();
System.out.println("请输入要读取的文件的路径");
String getSource = getFilePath.nextLine();
// lineRead(getSource);
oneRead(getSource);
}
}

g、 如何写文本数据;
分析:
XLIII、 使用输出流;
XLIV、 使用字符流;OutputStreamWriter
package day11.io;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;

public class WriteTextDataManager {
public static void main(String[] args) throws IOException {
File file = new File("src\\day11\\io\\b.txt");
//建立外界设备的输出低端流对象
OutputStream os = new FileOutputStream(file, true);
//建立程序中输出高端流对象
OutputStreamWriter osw = new OutputStreamWriter(os, Charset.defaultCharset());
//写数据
osw.write("你好!");
//清空缓存
osw.flush();
System.out.println("数据写入成功!");
//关闭流的对象
//从源头开始关闭
osw.close();
os.close();
}
}
自己的代码:
package day11.io;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.Scanner;

public class MyWriteTextDataManager {
// 定一个键盘输入的方法;
public static Scanner getScan() {
return new Scanner(System.in);
}

// 定义一个读取文件的方法;
public static void writerFile(String filePath) throws Exception {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
new File(filePath)), Charset.defaultCharset());
osw.write(filePath);
System.out.println("文件写入成功");
osw.flush();
osw.close();
}

public static void main(String[] args) throws Exception {
Scanner writerFilePath = getScan();
System.out.println("请输入要写入文件的路径");
String writerFilePathValues = writerFilePath.nextLine();
writerFile(writerFilePathValues);
}
}

a、 练习题;
将一个文件的内容迁移到另外一个文件中去
1)源文件存在,而且有内容
2)目标文件不存在,要新建的。
3)将源文件中的内容读取出来,然后写到目标文件中去。
package day12.practise;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Scanner;

public class FileCopyManager {

/**
* 键盘输入的方法
*
* @return
*/
public static BufferedReader getKey() {
return new BufferedReader(new InputStreamReader(System.in));
}

/**
* 键盘输入的方法
*
* @return
*/
public static Scanner getScan() {
return new Scanner(System.in);
}

/**
* 创建目标文件的方法
*
* @param destPath
* :目标的路径
* @return
* @throws IOException
*/
public static boolean createDestFile(String destPath) throws IOException {
File destFile = new File(destPath);
boolean result = destFile.createNewFile();
return result;
}

public static void copyFile(String sourcePath, String destPath)
throws IOException {
// File sourceFile = new File(sourcePath);
// File destFile = new File(destPath);
// 建立读取源文件的对象
InputStreamReader isr = new InputStreamReader(new FileInputStream(
sourcePath));
BufferedReader br = new BufferedReader(isr);
// 建立写数据的对象
PrintWriter pw = new PrintWriter(new FileOutputStream(destPath));

while (true) {
// 一边读取数据,一边写数据
String data = br.readLine();
if (data == null) {
break;
}
// 写数据
pw.println(data);
// 清空缓存
pw.flush();
}

System.out.println("复制成功!");
pw.close();
br.close();
}

public static void main(String[] args) throws IOException {
BufferedReader key = getKey();
boolean isDest = false;
while (true) {
System.out.println("请输入目标文件的路径:");
String destPath = key.readLine();

int index = 0;
try {
isDest = createDestFile(destPath);
// 如果以上不会发生异常,有2种结果:
/**
* false:输入路径正确,但是文件已经存在,所以创建目标文件失败 true:输入路径正确,目标文件不存在,所以创建成功
*
*/
if (isDest) {
index = 1;
System.out.println("请输入源文件的路径:");
String sourcePath = key.readLine();
copyFile(sourcePath, destPath);
} else {
System.out.println("目标文件已经存在,请输入别的文件名称!");
continue;
}
} catch (Exception e) {
if (index == 0) {
// 以上输入的目标文件的路径是错的,不存在的,所以会抛出一个FileNotFountException的异常。
System.out.println("输入的目标文件的路径不存在!");
continue;
} else {
System.out.println("输入的源文件的路径不存在!");
continue;
}
}
}
}
}
13、 Day13;
33. 文件的对象序列化和反序列化;
I、 对象:包装很多属性的JavaBean对象。
II、 对象必须实现一个接口:serializable接口,才能通过序列化(ObjectOutputstream)以及反序列化(ObjectInputStream)
III、 序列化过程相当于是将javaBean对象写到文件中去,而反序列化过程则相当于将javaBean对象从文件中读取出来。
代码:
package day13.serializable;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.Serializable;

public class Myserializable {
ObjectOutputStream objectOutputStream;
ObjectInputStream objectInputStream;
OutputStreamWriter outputStreamWriter;
File fileIn, fileOut;
Me me, me2;

public Myserializable(String fileOutPath) {
me = new Me("邹国良", "新港西路152号", 22);
me2 = new Me("刘亦菲", "朝阳路路152号", 25);
try {
objectOutputStream = new ObjectOutputStream(new FileOutputStream(
fileOutPath));
objectOutputStream.writeObject(me);
objectOutputStream.writeObject(me2);
System.out.println("已经成功序列化了");

objectInputStream = new ObjectInputStream(new FileInputStream(
fileOutPath));
me = (Me) objectInputStream.readObject();
System.out
.println("===============================接下来就是反序列化啦,请等1秒钟哈=========================");

Thread.sleep(1000);

System.out.println(me.toString());
me2 = (Me) objectInputStream.readObject();
System.out
.println("===============================接下来就是反序列化啦,请等1秒钟哈=========================");

Thread.sleep(1000);

System.out.println(me2.toString());
} catch (Exception e) {
e.printStackTrace();
}

}

public static void main(String[] args) {
new Myserializable("src/day13/serializable/hi.bat");
}

}

class Me implements Serializable {
private String name;
private String address;
private int age;

public Me(String name, String address, int age) {
this.name = name;
this.address = address;
this.age = age;
}

@Override
public String toString() {
return "名字:" + getName() + "; 地址:" + getAddress() + "; 年龄:"
+ getAge();
}

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

}
34. jdk 1.5的新特性;
b、 泛型(Generic);
  C++通过模板技术可以指定集合的元素类型,而Java在1.5之前一直没有相对应的功能。一个集合可以放任何类型的对象,相应地从集合里面拿对象的时候我们也不得不对他们进行强制得类型转换。猛虎引入了泛型,它允许指定集合里元素的类型,这样你可以得到强类型在编译时刻进行类型检查的好处。
Collection<String> c = new ArrayList();
c.add(new Date());
编译器会给出一个错误:
add(java.lang.String) in java.util.Collection<java.lang.String> cannot be applied to (java.util.Date)
c、 For-Each循环;
  For-Each循环得加入简化了集合的遍历。假设我们要遍历一个集合对其中的元素进行一些处理。典型的代码为:
void processAll(Collection c){
    for(Iterator i=c.iterator(); i.hasNext();){
        MyClass myObject = (MyClass)i.next();
        myObject.process();
    }
}
使用For-Each循环,我们可以把代码改写成:
void processAll(Collection<MyClass> c){
    for (MyClass  myObject :c)
        myObject.process();
}
这段代码要比上面清晰许多,并且避免了强制类型转换。
d、 自动装包/拆包(Autoboxing/unboxing);
自动装包/拆包大大方便了基本类型数据和它们包装类地使用。
自动装包:基本类型自动转为包装类.(int >> Integer)
自动拆包:包装类自动转为基本类型.(Integer >> int)
在JDK1.5之前,我们总是对集合不能存放基本类型而耿耿于怀,现在自动转换机制解决了我们的问题。
int a = 3;
Collection c = new ArrayList();
c.add(a);//自动转换成Integer.
Integer b = new Integer(2);
c.add(b + 2);
  这里Integer先自动转换为int进行加法运算,然后int再次转换为Integer.
e、  枚举(Enums);
  JDK1.5加入了一个全新类型的“类”-枚举类型。为此JDK1.5引入了一个新关键字enmu. 我们可以这样来定义一个枚举类型。
public enum Color
{
   Red,
   White,
   Blue
}
  然后可以这样来使用Color myColor = Color.Red.
  枚举类型还提供了两个有用的静态方法values()和valueOf(). 我们可以很方便地使用它们,例如
for (Color c : Color.values())
            System.out.println(c);
f、  可变参数(Varargs);

  可变参数使程序员可以声明一个接受可变数目参数的方法。注意,可变参数必须是函数声明中的最后一个参数。假设我们要写一个简单的方法打印一些对象,
util.write(obj1);
util.write(obj1,obj2);
util.write(obj1,obj2,obj3);

  在JDK1.5之前,我们可以用重载来实现,但是这样就需要写很多的重载函数,显得不是很有效。如果使用可变参数的话我们只需要一个函数就行了
public void write(Object... objs) {
   for (Object obj: objs)
      System.out.println(obj);
}
  在引入可变参数以后,Java的反射包也更加方便使用了。对于c.getMethod("test", new Object[0]).invoke(c.newInstance(), new Object[0])),现在我们可以这样写了c.getMethod("test").invoke(c.newInstance()),这样的代码比原来清楚了很多。 
g、 静态导入(Static Imports);
  要使用用静态成员(方法和变量)我们必须给出提供这个方法的类。使用静态导入可以使被导入类的所有静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出他们的类名。
import static java.lang.Math.*;
…….
r = sin(PI * 2); //无需再写r = Math.sin(Math.PI);
  不过,过度使用这个特性也会一定程度上降低代码地可读性。
Collection<String> c = new ArrayList();
c.add(new Date()); a

编译器会给出一个错误:
add(java.lang.String) in java.util.Collection<java.lang.String> cannot be applied to (java.util.Date)
14、 Day14;
35. 线程;
h、 产生线程的方式;
在java中要产生线程有两种方式;一种可以使继承Thread类在调用start()方法。另外一种是实现Runnable接口,在Thread实例,然后在调用run()方法。
M、 继承Thread类;
步骤:
1 继承 Thread
2 实现 run()
3、启动线程 实例对象.start();

那下面我们通过继承Thread类,来打印1····100;
package mySelf;
public class ThreadDemo extends Thread {
public static void main(String[] args) throws Exception {
ThreadDemo threadDemo = new ThreadDemo();
threadDemo.start();
}
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
}
}
}

N、 实现Runnable接口;
步骤:
1、实现 Runnable
2、实现 run()
3、new Thread(new BanDianNao()).start();
那下面我们通过实现Runable接口,来打印1····100;
package mySelf;
public class RunnableDemo implements Runnable {
public static void main(String[] args) {
new RunnableDemo().run();
}
public void run() {
for (int i = 1; i <= 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
}
}
}
i、 线程的状态;
线程的状态表示线程正在进行的活动以及在此时间段内所能完成的任务.线程有创建,可运行,运行中,阻塞,死亡五中状态.一个具有生命的线程,总是处于这五种状态之一:

O、 创建状态;
使用new运算符创建一个线程后,该线程仅仅是一个空对象,系统没有分配资源,称该线程处于创建状态(new thread)
P、 可运行状态;
使用start()方法启动一个线程后,系统为该线程分配了除CPU外的所需资源,使该线程处于可运行状态(Runnable)
Q、 运行中状态;
Java运行系统通过调度选中一个Runnable的线程,使其占有CPU并转为运行中状态(Running).此时,系统真正执行线程的run()方法.
R、 阻塞状态;
一个正在运行的线程因某种原因不能继续运行时,进入阻塞状态(Blocked)
S、 死亡状态;
线程结束后是死亡状态(Dead)
j、 注意;
1、线程的名字,一个运行中的线程总是有名字的,名字有两个来源,一个是虚拟机自己给的名字,一个是你自己的定的名字。在没有指定线程名字的情况下,虚拟机总会为线程指定名字,并且主线程的名字总是mian,非主线程的名字不确定。
2、线程都可以设置名字,也可以获取线程的名字,连主线程也不例外。
3、获取当前线程的对象的方法是:Thread.currentThread();
4、一系列线程以某种顺序启动并不意味着将按该顺序执行。对于任何一组启动的线程来说,调度程序不能保证其执行次序,持续时间也无法保证。
5、当线程目标run()方法结束时该线程死亡。
6、一旦线程启动,它就永远不能再重新启动。只有一个新的线程可以被启动,并且只能一次。
7、线程的调度是JVM的一部分,在一个CPU的机器上上,实际上一次只能运行一个线程。一次只有一个线程栈执行。JVM线程调度程序决定实际运行哪个处于可运行状态的线程。
众多可运行线程中的某一个会被选中做为当前线程。可运行线程被选择运行的顺序是没有保障的。
8、尽管通常采用队列形式,但这是没有保障的。队列形式是指当一个线程完成“一轮”时,它移到可运行队列的尾部等待,直到它最终排队到该队列的前端为止,它才能被再次选中。事实上,我们把它称为可运行池而不是一个可运行队列,目的是帮助认识线程并不都是以某种有保障的顺序排列唱呢个一个队列的事实。
9、尽管我们没有无法控制线程调度程序,但可以通过别的方式来影响线程调度的方式。
k、 线程总体分两类:用户线程和守候线程;
T、 同步;
线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏
U、 锁;
每个对象都有一个锁的,每个对象都有一个线程队列。
得到锁的步骤;
XLV、 准备一个对象
XLVI、 得到该对象的锁(本质是用同一个事物来做参照)
方式一:
static Object s=new Object();
synchronized(s){}

public synchronized void fn(){
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + n++);
}
}
方式二;
synchronized(MyThread.class){}
public synchronized static void fn(){
for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + ":" + n++);
}
}
最后关于锁和同步,有一下几个要点:
1)、只能同步方法,而不能同步变量和类;
2)、每个对象只有一个锁;当提到同步时,应该清楚在什么上同步?也就是说,在哪个对象上同步?
3)、不必同步类中所有的方法,类可以同时拥有同步和非同步方法。
4)、如果两个线程要执行一个类中的synchronized方法,并且两个线程使用相同的实例来调用方法,那么一次只能有一个线程能够执行方法,另一个需要等待,直到锁被释放。也就是说:如果一个线程在对象上获得一个锁,就没有任何其他线程可以进入(该对象的)类中的任何一个同步方法。
5)、如果线程拥有同步和非同步方法,则非同步方法可以被多个线程自由访问而不受锁的限制。
6)、线程睡眠时,它所持的任何锁都不会释放。
7)、线程可以获得多个锁。比如,在一个对象的同步方法里面调用另外一个对象的同步方法,则获取了两个对象的同步锁。
8)、同步损害并发性,应该尽可能缩小同步范围。同步不但可以同步整个方法,还可以同步方法中一部分代码块。
9)、在使用同步代码块时候,应该指定在哪个对象上同步,也就是说要获取哪个对象的锁。
来个程序来说明一下;
package day14.lock;

public class TestLock {
public static void main(String[] args) {
new MyThread().start();
new MyThread().start();
}

static class MyThread extends Thread {
public static int n = 0;

// 1 准备一个对象
// String s="h";
// String y="h";
// static Object s=new Object();
// Object s=new Object();
public void run() {
// 2 得到该对象的锁
fn();
fn2();
}

public synchronized static void fn() {
for (int i = 0; i < 10; i++) {
System.out
.println(Thread.currentThread().getName() + ":" + n++);
}
}

public static void fn2() {
}
}
}
36. Socket编程;
a、 何为Socket;
所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
图解;


I、典型例子一:通信
首先先建一个Server类:
package day13.net;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
public static void main(String[] args) {
try {
System.out.println("服务端启动~~~~~~~~");
ServerSocket ss = new ServerSocket(9999);
while (true) {
Socket so = ss.accept();
new MyThread(so).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

class MyThread extends Thread {
private Socket so;
private BufferedReader br;
public MyThread(Socket so) {
try {
this.so = so;
this.br = new BufferedReader(new InputStreamReader(
so.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}

public void run() {
try {
while (true) {
String line = br.readLine();
System.out.println("---MyThread----------" + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
再建一个client类:
package day13.net;

import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class MyClient {
public static void main(String[] args) {
try {
System.out.println("-----客户端------");
Socket so = new Socket("127.0.0.1", 9999);
PrintWriter pw = new PrintWriter(new OutputStreamWriter(
so.getOutputStream()));
Scanner scan = new Scanner(System.in);
while (true) {
String s = scan.next();
pw.println(s);
pw.flush();
}
// pw.close();
// so.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过以上两个类进行服务器与客户端之间的通信。
II、典型例子二:生产者与消费者:
先建一个生成这类


再建一个消费者类


最后再建一个仓库类


15、 Day15;
37. AWT;
b、 概念;
抽象窗口工具包AWT (Abstract Window Toolkit) 是 API为Java 程序提供的建立图形用户界面GUI (Graphics User Interface)工具集,AWT可用于Java的applet和applications中。
V、 它支持图形用户界面编程的功能包括;
I、 用户界面组件;
II、 事件处理模型;
III、 图形和图像工具,包括形状、颜色和字体类;
IV、 布局管理器,可以进行灵活的窗口布局而与特定窗口的尺寸和屏幕分辨率无关;
V、 数据传送类,可以通过本地平台的剪贴板来进行剪切和粘贴。
c、 Java.awt包;
这个包中提供了GUI设计所使用的列和接口,也提供了java程序的GUI工具,主要有一下三个:
XLVII、 组件------Component
XLVIII、 容器------Container
XLIX、 布局管理器------LayoutManager
a、 组件和容器;
组件是一个可以以图形化的方式显示在屏幕上的并且与用户互交的对象。比如一个按钮不能单独的显示出来,必须将组件放在容器中才可以显示出来的。
类Component是许多组件类的父类,component类中封装了组件通用的方法和属性,其相应的成员方法包括:
getComponentAt(int x, int y)
   getFont()
   getForeground()
   getName()
   getSize()
   paint(Graphics g)
   repaint()
   update()
   setVisible(boolean b)
   setSize(Dimension d)
   setName(String name)等,想要更详细的方法和属性请看帮助文档;
容器(container)也是一个类,是component的子类,也是一个组件,是容纳其他组件和容器。
在程序中安排组件的位置和大小时,应该注意以下两点:
  1.容器中的布局管理器负责各个组件的大小和位置,因此用户无法在这种情况下设置组件的这些属性。如果试图使用Java 语言提供的setLocation(),setSize(),setBounds() 等方法,则都会被布局管理器覆盖。
  2.如果用户确实需要亲自设置组件大小或位置,则应取消该容器的布局管理器,方法为:
   setLayout(null);
b、 常用容器;
有三种类型的容器:Window、Panel、ScrollPane,常用的有Panel, Frame, Applet
所有的容器都可以通过add()方法向容器添加组件。
W、 Frame;
import java.awt.*;
  public class MyFrame extends Frame{
  public static void main(String args[ ]){
        MyFrame fr = new MyFrame("Hello Out There!");
                       //构造方法
        fr.setSize(200,200);
                //设置Frame的大小,缺省为(0,0)
        fr.setBackground(Color.red);
                //设置Frame的背景,缺省为红色
        fr.setVisible(true);
                //设置Frame为可见,缺省为不可见
  }
     public MyFrame (String str){
        super(str); //调用父类的构造方法
     }
  }
X、 Panel;
import java.awt.*;
  public class FrameWithPanel extends Frame{
  public FrameWithPanel(String str){
        super(str);
      }

      public static void main(String args[]){
        FrameWithPanel fr = new FrameWithPanel("Frame with Panel");
        Panel pan=new Panel();
        fr.setSize(200,200);
        fr.setBackground(Color.red);
               //框架fr的背景颜色设置为红色
        fr.setLayout(null);
               //取消布局管理器
        pan.setSize(100,100);
        pan.setBackground(Color.yellow);
               //设置面板pan的背景颜色为黄色
        fr.add(pan); //用add方法把面板pan添加到框架fr中
        fr.setVisible(true);
        }
   }
c、 LayoutManager布局管理器;
布局管理器主要包括:FlowLayout,BorderLayout,GridLayout,CardLayout,GridBagLayout
Y、 FlowLayou;
FlowLayout 是Panel,Applet的缺省布局管理器。其组件的放置规律是从上到下、从左到右进行放置,如果容器足够宽,第一个组件先添加到容器中第一行的最左边,后续的组件依次添加到上一个组件的右边,如果当前行已放置不下该组件,则放置到下一行的最左边。

import java.awt.*;
    public class myButtons{
     public static void main(String args[])
     {
        Frame f = new Frame();
        f.setLayout(new FlowLayout());
        Button button1 = new Button("Ok");
        Button button2 = new Button("Open");
        Button button3 = new Button("Close");
        f.add(button1);
        f.add(button2);
        f.add(button3);
        f.setSize(300,100);
        f.setVisible(true);
     }
    }
Z、 BorderLayout;
BorderLayout 是Window,Frame和Dialog的缺省布局管理器。BorderLayout布局管理器把容器分成5个区域:North,South,East,West和Center,每个区域只能放置一个组件。各个区域的位置及大小如下图所示:

    

import java.awt.*;
    public class buttonDir{
     public static void main(String args[]){
      Frame f = new Frame("BorderLayout");
      f.setLayout(new BorderLayout());
      f.add("North", new Button("North"));
      //第一个参数表示把按钮添加到容器的North区域
      f.add("South", new Button("South"));
      //第一个参数表示把按钮添加到容器的South区域
      f.add("East", new Button("East"));
      //第一个参数表示把按钮添加到容器的East区域
      f.add("West", new Button("West"));
      //第一个参数表示把按钮添加到容器的West区域
      f.add("Center", new Button("Center"));
      //第一个参数表示把按钮添加到容器的Center区域
      f.setSize(200,200);
      f.setVisible(true);
     }
    }
AA、 GridLayout;
使容器中各个组件呈网格状布局,平均占据容器的空间

import java.awt.*;
    public class ButtonGrid {
    public static void main(String args[]) {
      Frame f = new Frame("GridLayout");
      f.setLayout(new GridLayout(3,2));
                 //容器平均分成3行2列共6格
      f.add(new Button("1")); //添加到第一行的第一格
      f.add(new Button("2")); //添加到第一行的下一格
      f.add(new Button("3")); //添加到第二行的第一格
      f.add(new Button("4")); //添加到第二行的下一格
      f.add(new Button("5")); //添加到第三行的第一格
      f.add(new Button("6")); //添加到第三行的下一格
      f.setSize(200,200);
      f.setVisible(true);
    }
    }
BB、 CardLayout;
CardLayout布局管理器能够帮助用户处理两个以至更多的成员共享同一显示空间,它把容器分成许多层,每层的显示空间占据整个容器的大小,但是每层只允许放置一个组件,当然每层都可以利用Panel来实现复杂的用户界面。牌布局管理器(CardLayout)就象一副叠得整整齐齐的扑克牌一样,有54张牌,但是你只能看见最上面的一张牌,每一张牌就相当于牌布局管理器中的每一层。

import java.awt.*;
 import java.awt.event.*; //事件处理机制,下一节的内容
 public class ThreePages implements MousListener {
    CardLayout layout=new CardLayout(); //实例化一个牌布局管理器对象
    Frame f=new Frame("CardLayout");
    Button page1Button;
    Label page2Label; //Label是标签,实际上是一行字符串
    TextArea page3Text; //多行多列的文本区域
    Button page3Top;
    Button page3Bottom;
 public static void main(String args[])
 { new ThreePages().go(); }

 Public void go()
 {   f.setLayout(layout); //设置为牌布局管理器layout
    f.add(page1Button=new Button("Button page"),"page1Button"); /*第二个参数"page1Button"表示的是你对这层牌所取的名字*/
    page1Button.addMouseListener(this); //注册监听器
    f.add(page2Label=new Label("Label page"),"page2Label");
    page2Label.addMouseLisener(this); //注册监听器
    Panel panel=new Panel();
    panel.setLayout(new BorderLayout());
    panel.add(page3Text=new TextArea("Composite page"),"Center");
    page3Text.addMouseListener(this);
    panel.add(page3Top=new Button("Top button") , "North");
    page3Top.addMouseListener(this);
    panel.add(page3Bottom=new Button("Bottom button") ,"South");
    page3Bottom.addMouseListener(this);
    f.add(panel,"panel");
    f.setSize(200,200);
    f.setVisible(true);
 }
 ……
 }
d、 容器的嵌套;
在复杂的图形用户界面设计中,为了使布局更加易于管理,具有简洁的整体风格,一个包含了多个组件的容器本身也可以作为一个组件加到另一个容器中去,容器中再添加容器,这样就形成了容器的嵌套。下面是一个容器嵌套的例子。
import java.awt.*;
    public class ExGui3{
    private Frame f;
    private Panel p;
    private Button bw,bc;
    private Button bfile,bhelp;
       public static void main(String args[])
       {
         ExGui3 gui = new ExGui3();
         gui.go();
       }
    public void go(){
       f = new Frame("GUI example 3");
       bw=new Button("West");
       bc=new Button("Work space region");
       f.add(bw,"West");
       f.add(bc,"Center");
       p = new Panel();
       f.add(p,"North");
       bfile= new Button("File");
       bhelp= new Button("Help");
       p.add(bfile);
       p.add(bhelp);
       f.pack();
       f.setVisible(true);
    }
    }
e、 小结;
1.Frame是一个顶级窗口。Frame的缺省布局管理器为BorderLayout。
   2.Panel 无法单独显示,必须添加到某个容器中。 Panel 的缺省布局管理器为FlowLayout。
   3.当把Panel 作为一个组件添加到某个容器中后,该Panel 仍然可以有自己的布局管理器。因此,可以利用Panel 使得BorderLayout 中某个区域显示多个组件,达到设计复杂用户界面的目的 。
  4.如果采用无布局管理器 setLayout(null),则必须使用setLocation(),setSize(),setBounds()等方法手工设置组件的大小和位置,此方法会导致平台相关,不鼓励使用。


38. Swing;
f、 基本容器Jframe;
CC、 第一个JFrame窗体程序;
public class JFrameDemo {

public static void main(String[] args) {
JFrame jf = new JFrame("这是我的第一个swing窗体");
Dimension d = new Dimension(300, 200);
jf.setSize(d);

Point p = new Point(500, 400);
jf.setLocation(p);

jf.setVisible(true);
}
}

g、 标签组件Jlabel;
DD、 定义标签对象;
public class JLabelDemo {

public static void main(String[] args) {
JFrame jf = new JFrame("这是我的第一个swing窗体");
JLabel lab = new JLabel("KENDE", JLabel.CENTER);//实例化标签对象
jf.add(lab);//将Label组件添加到JFrame面板中
Dimension d = new Dimension(300, 200);
jf.setSize(d);
Point p = new Point(500, 400);
jf.setLocation(p);
jf.setVisible(true);
}
}

EE、 定义标签字体;
标签可以设置字体,包括什么字体,字体的颜色,大小,是否斜体等
public class JLabelDemo2 {
public static void main(String[] args) {
JFrame jf = new JFrame("这是我的第一个swing窗体");
JLabel lab = new JLabel("KENDE", JLabel.CENTER);//实例化标签对象
Font font = new Font("Dialog", Font.ITALIC + Font.BOLD, 30);
lab.setFont(font);
jf.add(lab);//将组件添加到面板中
Dimension d = new Dimension(300, 200);
jf.setSize(d);
Point p = new Point(500, 400);
jf.setLocation(p);
jf.setVisible(true);
}
}
FF、 得到本机中所有的字体;
public class GetAllFonts {
public static void main(String[] args) {
GraphicsEnvironment g = GraphicsEnvironment
.getLocalGraphicsEnvironment();
String fonts[] = g.getAvailableFontFamilyNames();
for (String name: fonts) {
System.out.println(name);
}
}
}

GG、 Label中设置显示的图片;
public class JLabelDemo3 {
public static void main(String[] args) {
JFrame jf = new JFrame("这是我的第一个swing窗体");
Icon icon = new ImageIcon("E:\\picBackGroud\\野生动物王国.jpg");
JLabel lab = new JLabel("KENDE", icon, JLabel.CENTER);// 实例化标签对象
Font font = new Font("Serif", Font.ITALIC + Font.BOLD, 30);
lab.setFont(font);
jf.add(lab);// 将组件添加到面板中
Dimension d = new Dimension(300, 200);
jf.setSize(d);
Point p = new Point(500, 400);
jf.setLocation(p);
jf.setVisible(true);
}
}
h、 第三节 按钮组件Jbutton
HH、 在JFrame中增加按钮;
public class JButtonDemo01 {
public static void main(String[] args) {
JFrame frame = new JFrame("Welcome to Kende's home!");
JButton bt = new JButton("按钮");
frame.add(bt);
frame.setSize(300,200);
frame.setLocation(400, 300);
frame.setVisible(true);
}
}
II、 往JButton中添加图片;
public class JButtonDemo02 {
public static void main(String[] args) {
JFrame frame = new JFrame("Welcome to Kende's home!");
String picPath = "E:\\picBackGroud\\a.jpg";
Icon icon = new ImageIcon(picPath);
JButton bt = new JButton(icon);
frame.add(bt);
frame.setSize(800,500);
frame.setLocation(400, 300);
frame.setVisible(true);
}
}

i、 布局管理器;
JJ、 FlowLayout布局管理器;
FlowLayout属于流式布局管理器,使用此种布局方式,所有的组件会像流水一样依次排列。
public class FlowLayoutDemo01 {
public static void main(String[] args) {
JFrame frame = new JFrame("Welcome to kende's home");
frame.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 20));
JButton button = null;
for(int i = 0; i < 9; i ++){
button = new JButton("按钮-" + i);
frame.add(button);
}
frame.setSize(800,500);
frame.setLocation(400, 300);
frame.setVisible(true);
}
}
效果图:


KK、 BorderLayout布局管理器;
BorderLayout将一个窗体的版面划成东,西,南,北,中五个区域,可以直接将需要的组件放到五个区域即可
public class BorderLayoutDemo01 {
public static void main(String[] args) {
JFrame frame = new JFrame("Welcome to kende's home");
frame.setLayout(new BorderLayout(20, 20));
frame.add(new JButton("东"), BorderLayout.EAST);
frame.add(new JButton("西"), BorderLayout.WEST);
frame.add(new JButton("南"), BorderLayout.SOUTH);
frame.add(new JButton("北"), BorderLayout.NORTH);
frame.add(new JButton("中"), BorderLayout.CENTER);
frame.setSize(500,300);
frame.setLocation(400, 300);
frame.setVisible(true);
}
}


LL、 GridLayout布局管理器;
GridLayout布局管理器是以表格的形式进行管理的,在使用此布局管理器的时候必须设置显示的行数和列数。
public class GridLayoutDemo01 {
public static void main(String[] args) {
JFrame frame = new JFrame("Welcome to kende's home");
frame.setLayout(new GridLayout(3, 5, 3, 3));
JButton button = null;
for(int i = 0; i < 13; i ++){
button = new JButton("按钮-" + i);
frame.add(button);
}
frame.setSize(500,300);
frame.setLocation(400, 300);
frame.setVisible(true);
}
}
效果图:

MM、 CardLayout布局管理器;
CardLayout就是将一组组件彼此重叠的进行布局,就像一张张卡片一样,这样每次只会展现一个界面
public class CardLayoutDemo01 {
public static void main(String[] args) {
JFrame frame = new JFrame("Welcome to kende's home");
CardLayout card = new CardLayout();
frame.setLayout(card);
Container con = frame.getContentPane();
con.add(new JLabel("标签-A", JLabel.CENTER), "first");
con.add(new JLabel("标签-B", JLabel.CENTER), "second");
con.add(new JLabel("标签-C", JLabel.CENTER), "third");
con.add(new JLabel("标签-D", JLabel.CENTER), "fourth");
con.add(new JLabel("标签-E", JLabel.CENTER), "fifth");
frame.pack();
frame.setVisible(true);
card.show(con, "third");
for (int i = 0; i < 5; i++) {
card.next(con);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
NN、 绝对定位;
以上的布局管理器都是依靠专门的工具完成,在java中也可以通过绝对定位的方式完成
public class AbsoluteLayoutDemo01 {
public static void main(String[] args) {
JFrame frame = new JFrame("Welcome to kende's home");
frame.setLayout(null);
JLabel title = new JLabel("www.togogo.net");
JButton enter = new JButton("进入");
JButton help = new JButton("帮助");
frame.setSize(500, 400);
frame.setLocation(300, 200);
title.setBounds(45, 5, 150, 20);
enter.setBounds(280, 30, 100, 80);
help.setBounds(100, 50, 200, 100);
frame.add(title);
frame.add(enter);
frame.add(help);
frame.setVisible(true);
}
}
效果图:

j、 其他容器;
OO、 Jpanel;
最早是在JFrame中加入组件,但是现在可以将组件加入到Jpanel中,在Jpanel中完成各个组件的排列,之后再将所有独立的Jpanel直接放在JFrame之中,以完成复杂的图形显示。
public class JPanelDemo01 {
public static void main(String[] args) {
JFrame frame = new JFrame("Welcome to kende's home");
JPanel panel = new JPanel();
panel.add(new JLabel("标签-1"));
panel.add(new JLabel("标签-2"));
panel.add(new JLabel("标签-3"));
panel.add(new JButton("按钮-X"));
panel.add(new JButton("按钮-Y"));
panel.add(new JButton("按钮-Z"));
frame.add(panel);
frame.pack();
frame.setLocation(300, 200);
frame.setVisible(true);
}
}


在开发中可以使用Jpanel完成一些复杂的界面设计。
PP、 JsplitPane;
JSplitPane的主要作用是分割面板,可以将一个窗体分为两个子窗体,可以是水平排列也可以是垂直排列
public class JSplitPaneDemo01 {
public static void main(String[] args) {
JFrame frame = new JFrame("Welcome to kende's home");
Container cont = frame.getContentPane();
JSplitPane lfsplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
new JLabel("标签-左"), new JLabel("标签-右"));
JSplitPane tpsplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, lfsplit,
new JLabel("标签-下"));
lfsplit.setDividerSize(30);
tpsplit.setDividerSize(20);
tpsplit.setOneTouchExpandable(true);
//frame.add(tpsplit);
cont.add(tpsplit);
frame.pack();
frame.setLocation(300, 200);
frame.setVisible(true);
}
}
效果图:

QQ、 JtabbedPane;
public class JTabbedPaneDemo01 {
public static void main(String[] args) {
JFrame frame = new JFrame("Welcome to kende's home");
Container cont = frame.getContentPane();
JTabbedPane tab = new JTabbedPane(JTabbedPane.TOP);
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
panel1.add(new JButton("按钮"));
panel2.add(new JLabel("标签"));
tab.addTab("图片选项", new ImageIcon("d:\\oracle.jpg"), panel1, "图片");
tab.addTab("文字选项", panel2);
cont.add(tab);
frame.pack();
frame.setLocation(300, 200);
frame.setVisible(true);
}
}
效果图:


RR、 JscrollPane;
在一般的图形界面中如果显示的区域不够大,往往会出现滚动条以方便用户浏览,在Swing中JScrollPane的主要功能就是为显示的内容加入水平滚动条。
JScrollPane主要由JViewPort和JScrollBar两部分组成,前者主要是显示一个矩形的区域让用户浏览,而后者主要是形成水平或者垂直的滚动条。

public class JScrollPaneDemo01 {
public static void main(String[] args) {
JFrame frame = new JFrame("Welcome to kende's home");
Container cont = frame.getContentPane();
String picPath = "d:" + File.separator + "oracle.jpg";
JLabel lab = new JLabel(new ImageIcon(picPath));
JPanel panel = new JPanel();
JScrollPane scrollPane = new JScrollPane(panel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

panel.add(lab);
cont.add(scrollPane);
frame.pack();
frame.setLocation(300, 200);
frame.setVisible(true);
}
}
效果图:

k、 第六节 事件处理;
Java事件处理流程:


SS、 关闭窗口;
在此之前的事件是无效的,窗体关闭也是无效的,如果现在要变得有效,必须加入事件处理机制
class MyWindowEventHandle implements WindowListener{
public void windowActivated(WindowEvent e){
System.out.println("windowActivated --> 窗口被选中") ;
}
public void windowClosed(WindowEvent e){
System.out.println("windowClosed --> 窗口被关闭") ;
}
public void windowClosing(WindowEvent e){
System.out.println("windowClosing --> 窗口关闭") ;
System.exit(1) ;
}
public void windowDeactivated(WindowEvent e){
System.out.println("windowDeactivated --> 取消窗口选中") ;
}
public void windowDeiconified(WindowEvent e){
System.out.println("windowDeiconified --> 窗口从最小化恢复") ;
}
public void windowIconified(WindowEvent e){
System.out.println("windowIconified --> 窗口最小化") ;
}
public void windowOpened(WindowEvent e){
System.out.println("windowOpened --> 窗口被打开") ;
}
};

public class MyEventWindowEventJFrame01{
public static void main(String args[]){
JFrame frame = new JFrame("Welcome To kende's home") ;
frame.addWindowListener(new MyWindowEventHandle()) ; // 加入事件
frame.setSize(300,150) ;
frame.setBackground(Color.WHITE) ;
frame.setLocation(300,200) ;
frame.setVisible(true) ;
}
}
注意:发现以上程序虽然实现了窗口关闭,但是没有必要实现那么多的方法,可以如何做呢,其实在事件中提供了很多的适配器
class MyWindowEventHandle2 extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.out.println("windowClosing --> 窗口关闭") ;
System.exit(1) ;
}
};

public class MyEventWindowEventJFrame02{
public static void main(String args[]){
JFrame frame = new JFrame("Welcome To kende’s home") ;
frame.addWindowListener(new MyWindowEventHandle2()) ; // 加入事件
frame.setSize(300,150) ;
frame.setBackground(Color.WHITE) ;
frame.setLocation(300,200) ;
frame.setVisible(true) ;
}
}
现在只要求一个关闭,资源太浪费了,可以使用匿名内部类的做法减少代码量
public class MyEventWindowEventJFrame03{
public static void main(String args[]){
JFrame frame = new JFrame("Welcome To kende’s home") ;
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.out.println("windowClosing --> 窗口关闭") ;
System.exit(1) ;
}
}) ; // 加入事件
frame.setSize(300,150) ;
frame.setBackground(Color.WHITE) ;
frame.setLocation(300,200) ;
frame.setVisible(true) ;
}
}
TT、 按钮事件;
如果要使得按钮有效,那么只需要使用ActionListener接口
class ActionHandle{
private JFrame frame = new JFrame("Welcome To kende's home") ;
private JButton but = new JButton("显示");
private JLabel lab = new JLabel() ;
private JTextField text = new JTextField(10) ;
private JPanel pan = new JPanel() ;
public ActionHandle(){
Font fnt = new Font("Serief",Font.ITALIC + Font.BOLD,28) ;
lab.setFont(fnt) ; // 设置标签的显示文字
lab.setText("等待用户输入信息!") ;
but.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
// if(e.getSource() instanceof JButton){} // 判断是否是按钮
if(e.getSource()==but){
lab.setText(text.getText()) ;
}
}
}) ;
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(1) ;
}
}) ; // 加入事件
frame.setLayout(new GridLayout(2,1)) ;
pan.setLayout(new GridLayout(1,2)) ;
pan.add(text);
pan.add(but) ;
frame.add(pan) ;
frame.add(lab) ;
frame.pack() ;
frame.setBackground(Color.WHITE) ;
frame.setLocation(300,200) ;
frame.setVisible(true) ;

}
};

public class MyActionEventDemo01{
public static void main(String args[]){
new ActionHandle() ;
}
}
完成一个简单的用户登录,用户名是kende,密码是123
class LoginCheck{
private String name ;
private String password ;
public LoginCheck(String name,String password){
this.name = name ;
this.password = password ;
}
public boolean validate(){
if("kende".equals(name)&&"123".equals(password)){
return true ;
}else{
return false ;
}
}
};

class ActionHandle2{
private JFrame frame = new JFrame("Welcome To kende's home") ;
private JButton submit = new JButton("登陆");
private JButton reset = new JButton("重置");
private JLabel nameLab = new JLabel("用户名:") ;
private JLabel passLab = new JLabel("密 码:") ;
private JLabel infoLab = new JLabel("用户登陆系统") ;
private JTextField nameText = new JTextField(10) ;
private JPasswordField passText = new JPasswordField() ;
private JPanel pan = new JPanel() ;
public ActionHandle2(){
Font fnt = new Font("Serief",Font.ITALIC + Font.BOLD,12) ;
infoLab.setFont(fnt) ; // 设置标签的显示文字
submit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(e.getSource()==submit){
String tname = nameText.getText() ;
String tpass = new String(passText.getPassword()) ;
LoginCheck log = new LoginCheck(tname,tpass) ;
if(log.validate()){
infoLab.setText("登陆成功,欢迎光临!") ;
}else{
infoLab.setText("登陆失败,错误的用户名或密码!") ;
}
}
}
}) ;
reset.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(e.getSource()==reset){
nameText.setText("") ;
passText.setText("") ;
infoLab.setText("用户登陆系统") ;
}
}
}) ;

frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(1) ;
}
}) ; // 加入事件
frame.setLayout(null) ;
nameLab.setBounds(5,5,60,20) ;
passLab.setBounds(5,30,60,20) ;
infoLab.setBounds(5,65,220,30) ;
nameText.setBounds(65,5,100,20) ;
passText.setBounds(65,30,100,20) ;
submit.setBounds(165,5,60,20) ;
reset.setBounds(165,30,60,20) ;
frame.add(nameLab) ;
frame.add(passLab) ;
frame.add(infoLab) ;
frame.add(nameText) ;
frame.add(passText) ;
frame.add(submit) ;
frame.add(reset) ;
frame.setSize(280,130) ;
frame.setBackground(Color.WHITE) ;
frame.setLocation(300,200) ;
frame.setVisible(true) ;

}
};

public class MyActionEventDemo03{
public static void main(String args[]){
new ActionHandle2() ;

}
}
UU、 键盘事件;
class MyKeyHandle extends JFrame implements KeyListener{
private JTextArea text = new JTextArea() ;
public MyKeyHandle(){
super.setTitle("Welcome To kende's home") ;
JScrollPane scr = new JScrollPane(text) ;
scr.setBounds(5,5,300,200) ;
super.add(scr) ;
text.addKeyListener(this) ;
super.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(1) ;
}
}) ; // 加入事件
super.setSize(310,210) ;
super.setVisible(true) ;
}
public void keyPressed(KeyEvent e){
text.append("键盘“" + KeyEvent.getKeyText(e.getKeyCode())+ "”键按下\n") ;
}

public void keyReleased(KeyEvent e){
text.append("键盘“" + KeyEvent.getKeyText(e.getKeyCode())+ "”键松开\n") ;
}

public void keyTyped(KeyEvent e){
text.append("输入的内容是:" + e.getKeyChar() + "\n") ;
}
};

public class MyKeyEventDemo01{
public static void main(String args[]){
new MyKeyHandle() ;
}
}
以上的键盘事件中,类必须要实现接口中的所有方法,太麻烦,那么在swing中也提供了键盘处理的Adapter类,直接使用此类即可。
class MyKeyHandle2 extends JFrame{
private JTextArea text = new JTextArea() ;
public MyKeyHandle2(){
super.setTitle("Welcome To kende's home") ;
JScrollPane scr = new JScrollPane(text) ;
scr.setBounds(5,5,300,200) ;
super.add(scr) ;
text.addKeyListener(new KeyAdapter(){
public void keyTyped(KeyEvent e){
text.append("输入的内容是:" + e.getKeyChar() + "\n") ;
}
}) ;
super.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(1) ;
}
}) ; // 加入事件
super.setSize(310,210) ;
super.setVisible(true) ;
}
};

public class MyKeyEventDemo02{
public static void main(String args[]){
new MyKeyHandle2() ;
}
}
VV、 鼠标事件;
class MyMouseHandle extends JFrame implements MouseListener{
private JTextArea text = new JTextArea() ;
public MyMouseHandle(){
super.setTitle("Welcome To kende's home") ;
JScrollPane scr = new JScrollPane(text) ;
scr.setBounds(5,5,300,200) ;
super.add(scr) ;
text.addMouseListener(this) ;
super.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(1) ;
}
}) ; // 加入事件
super.setSize(310,210) ;
super.setVisible(true) ;
}
public void mouseClicked(MouseEvent e){
int c = e.getButton() ;
String mouseInfo = null ;
if(c==MouseEvent.BUTTON1){
mouseInfo = "左键" ;
}
if(c==MouseEvent.BUTTON3){
mouseInfo = "右键" ;
}
if(c==MouseEvent.BUTTON2){
mouseInfo = "滚轴" ;
}
text.append("鼠标单击:" + mouseInfo + "\n") ;
}

public void mouseEntered(MouseEvent e){
text.append("鼠标进入组件。\n") ;
}
public void mouseExited(MouseEvent e){
text.append("鼠标离开组件。\n") ;
}
public void mousePressed(MouseEvent e){
text.append("鼠标按下。\n") ;
}
public void mouseReleased(MouseEvent e){
text.append("鼠标松开。\n") ;
}
};
public class MyMouseEventDemo01{
public static void main(String args[]){
new MyMouseHandle() ;
}
}
鼠标中也提供了Adapter类,可以减少代码
class MyMouseHandle2 extends JFrame{
private JTextArea text = new JTextArea() ;
public MyMouseHandle2(){
super.setTitle("Welcome To kende's home") ;
JScrollPane scr = new JScrollPane(text) ;
scr.setBounds(5,5,300,200) ;
super.add(scr) ;
text.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
int c = e.getButton() ;
String mouseInfo = null ;
if(c==MouseEvent.BUTTON1){
mouseInfo = "左键" ;
}
if(c==MouseEvent.BUTTON3){
mouseInfo = "右键" ;
}
if(c==MouseEvent.BUTTON2){
mouseInfo = "滚轴" ;
}
text.append("鼠标单击:" + mouseInfo + "\n") ;
}
}) ;
super.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(1) ;
}
}) ; // 加入事件
super.setSize(310,210) ;
super.setVisible(true) ;
}
};

public class MyMouseEventDemo02{
public static void main(String args[]){
new MyMouseHandle2() ;
}
}
WW、 鼠标拖拽事件;
在swing事件中可以使用MouseMotionListener接口完成鼠标的拖拽
class MyMouseMotionHandle extends JFrame{
public MyMouseMotionHandle(){
super.setTitle("Welcome To kende's home") ;
super.addMouseMotionListener(new MouseMotionListener(){
public void mouseDragged(MouseEvent e){
System.out.println("鼠标拖拽到:X = " + e.getX() + ",Y = " + e.getY()) ;
}
public void mouseMoved(MouseEvent e){
System.out.println("鼠标移动到窗体。") ;
}
}) ;
super.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(1) ;
}
}) ; // 加入事件
super.setSize(310,210) ;
super.setVisible(true) ;
}
};

public class MyMouseMotionEventDemo01{
public static void main(String args[]){
new MyMouseMotionHandle() ;
}
}
在程序中也本身包含了Adapter类,直接使用此类完成此功能
class MyMouseMotionHandle2 extends JFrame{
public MyMouseMotionHandle2(){
super.setTitle("Welcome To kende's home") ;
super.addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
System.out.println("鼠标拖拽到:X = " + e.getX() + ",Y = " + e.getY()) ;
}
}) ;
super.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(1) ;
}
}) ; // 加入事件
super.setSize(310,210) ;
super.setVisible(true) ;
}
};

public class MyMouseMotionEventDemo02{
public static void main(String args[]){
new MyMouseMotionHandle2() ;
}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值