1.
扩展的赋值运算符其实隐含了一个强制类型转换
s += 1;
等价于 s = (s的数据类型)(s+1)
2.
键盘录入
①import java.util.Scanner;
②Scanner sc = new Scanner(System.in);
③int x = sc.nextInt();
3.
implements 是实现接口的关键字(里面有对接口抽象方法的具体实现)
interface 是代表接口的名词
abstract 是抽象类
extend不支持多继承方法,implements继承只能继承一个类,但是用implements来实现多个接口,用逗号隔开。
形式是:class A extends D implements B,C
定义一个接口的时候用 Interface
在使用这个接口的时候用implements
4.
类的关系图示中:
—> (实线箭头)表示继承
--> (虚线箭头)表示接口类interface
— (实线) 表示接口的具体实现类implements
5.
extend 设置泛型上限(父类)
super 设置泛型下限(子类)
通常对集合中的元素进行取出操作时,可以用下限
6.
集合的一些技巧
需要唯一吗?
需要:Set
需要制定顺序:
需要:TreeSet
不需要:HashSet
但是想要一个和存储一致的顺序:有序:LinkHashSet
不需要:List
需要频繁增删吗?
需要:LinkedList
不需要:ArrayList
7.
Runtime没有构造方法摘要,说明这类不可以创建对象。
又发现还有非静态的方法,说明这类应该提供静态的返回该类对象的方法
而且只有一个,说明Runtime类使用了单例设计模式。
8.
字节流的两个顶层父类
①InputStream ②OutputStream
字符流的两个顶层父类
①Reader ②Writer
//需求:将一些文字存储到硬盘的一个文件中
记住,如果要操作文字数据,建议优先考虑字符流
而且要将数据从内存写到硬盘上,要使用字符流中的输出流Writer
既然是往一个文件中写入数据,那么在创建对象是,就必须明确文件
文件不存在,则自动创建
文件存在,则会被覆盖
eg. FileWriter fw = new FileWriter("demo.txt");
如果构造函数中加入true,可以实现对文件进行续写
//需求:读取一个文本文件,将读取的字符打印到控制台
①创建读取字符数据的流对象
在创建读取流对象时,必须要明确被读取的文件,及文件必须存在
用一个读取流关联一个已存在文件
FileReader fr = new FileReader("demo.txt");
//使用read方法读取单个字符
9.
装饰设计模式:对一组对象的功能进行增强时,就可以使用该模式进行问题的解决
继承和装饰都能实现对功能的拓展增强
有什么区别呢?
装饰比继承更为灵活
特点:装饰和被装饰类都必须所属于同一个借口或者父类
10.
转换流:
InputStreamReader:字节到字符的桥梁,解码。
OutputStreamWriter:字符到字节的桥梁,编码。
流的操作规律:
之所以要弄清楚这个规律,是因为流对象太多,开发是不知道用哪个对象合适
想要知道开发时用到哪些对象,只要通过四个明确即可
①明确源和目的(汇)
源:InputStream Reader
目的:OutputStream Writer
②明确数据是否是纯文本数据
源:是纯文本:Reader
否:InputStream
目的:是纯文本: Writer
否:OutputStream
③明确具体的设备
源设备:
硬盘:File
键盘:System.in
内存:数组
网络:Socket流
目的设备:
硬盘:File
控制台:System.out
内存:数组
网络:Socket流
④是否需要其他额外功能
1.是否需要高效(缓冲区):
是:就加上buffer
需求1:复制一个文本文件。
1.明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
2.是否是纯文本?
是:
源:Reader
目的:Writer
3.明确具体设备
源:
硬盘:File
目的:
硬盘:File
FileReader fr = new FileReader("a.txt")
FileWriter fw = new FileWriter("b.txt")
4.需要额外功能吗?
需要:需要高效
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
需求2:读取键盘录入信息,并写入到一个文件中。
1.明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
2.是否是纯文本?
是:
源:Reader
目的:Writer
3.明确具体设备
源:
键盘:System.in
目的:
硬盘:File
InputStream is = System.in;
FileWriter fw = new FileWriter("b.txt");
这样做就可以完成,但是麻烦,将读取的字节数据转成字符串,再有字符流操作。
4.需要额外功能吗?
需要:转换,将字节流转成字符流,因为明确的源是Reader,这样操作文本数据更便捷
所以要将已有的字节流转成字符流,使用到字节—>字符,InputStreamReader;
InputStreamReader isr = new InputStream(System.in);
FileWriter fw = new FileWriter("b.txt");
还需要功能想高效
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt");
需求3:将一个文件文件数据显示在控制台上
1.明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
2.是否是纯文本?
是:
源:Reader
目的:Writer
3.明确具体设备
源:
硬盘:File
目的:
控制台:System.out
FileReader fr = new FileReader("a.txt");
OutputStream out = System.out;
4.需要额外功能吗?
需要,转换:
FileReader fr = new FileReader("a.txt");
OutputStreamWriter osw = new OutputStreamWriter(System.out));
需要,高效
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter(System.out));
需求4:读取键盘录入数据,显示在控制台上
1.明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
2.是否是纯文本?
是:
源:Reader
目的:Writer
3.明确设备
源:
键盘:System.in
目的:
控制台:System.out
InputStream is = System.in;
OutputStream os = System.out;
4.明确额外功能
需要转换,因为是字节流,但是操作的却是文本数据
所以使用字符流操作起来更为便捷
InputStreamReader isr = new InputStreamReader(System.in);
OutputStreamWriter osw = new OutputStreamWriter(System.out);
为了使其高效
BufferedStreamReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedStreamWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
需求5:将一个中文字符串数据按指定的编码表写入到一个文本文件中
1.目的:OutputStream Writer
2.是纯文本:Writer
3.设备:键盘File
FileWriter fw = new FileWriter("a.txt");
fw.writer("你好");
注意:既然需求中已经明确了指定的编码表的的动作
那就不可以使用FileWriter ,因为FileWriter内部是使用默认的本地码表
只能使用其父类,OutputStreamWriter;
OutputStreamWriter接收一个字节输出流对象,既然是操作文件,那么该对象应该是FileOutputStream
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"),charsetName);
需要高效:
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt").charsetName));
什么时候使用转换流呢
1.源或目的对应得设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁
提高对文本操作的便捷
2.一旦操作文本涉及到具体的指定编码表时,必须使用转换流。
11.
抽象类(abstract class)和接口(instance)的联系和区别:
1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2、抽象类要被子类继承,接口要被类实现。
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6、抽象方法只能申明,不能实现。abstract void abc();不能写成abstract void abc(){}。
7、抽象类里可以没有抽象方法
8、如果一个类里有抽象方法,那么这个类只能是抽象类
9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
10、接口可继承接口,并可多继承接口,但类只能单根继承。
特别是对于公用的实现代码,抽象类有它的优点。抽象类能够保证实现的层次关系,避免代码重复。然而,即使在使用抽 象类的场合,也不要忽视通过接口定义行为模型的原则。从实践的角度来看,如果依赖于抽象类来定义行为,往往导致过于复杂的继承关系,而通过接口定义行为能 够更有效地分离行为与实现,为代码的维护和修改带来方便。
12.
系统找不到指定文件
问题在:d:\test.txt这个文件。此文件没有扩展名(即不用写文件扩展名)
解决方法:电脑工具栏-文件夹选项(左上方)-查看-高级设置:-隐藏已知文件类型的扩展名(勾选去掉-应用-确定)
13.
如何添加插件?(使用JFrame图形化界面操作Swing)
File-->New-->Other-->Wizards中选择相关文件
(如要用更加图形化的操作Swing选择WindowsBuider下的Swing Design中的JFrame)
14.
发送与接收可以打开2个console窗口观察演示,注意选择DisplaySelectConsole
15.
常用dos命令
可以在命令提示符中使用
../ 上一层目录
md 文件夹名 新建文件夹
cd 文件夹名 进入到该目录(重要)
cd.. 返回上一层目录
cd\ 返回根目录
cd.>文件名 新建文件
rd 文件夹名 删除文件夹(只能删除空文件夹)
copy 文件(夹)名1 文件(夹)名2 1复制到2中
move 文件(夹)名1 文件(夹)名2 1剪切到2中
del 文件名 删除文件
del 文件夹名 删除文件夹内的所有文件
ren 文件(夹)名1 文件(夹)名2 将名字1改成名字2
dir 文件夹名 查看该目录下的所有文件信息
type 文件名 查看文件内容
16.
在cmd下运行java程序时注意目录中加上包名
eg. java 包名.class文件名 (java和包名之间有空格)
同时,用java命令时,应该运行的是class文件,在bin文件夹中,src中的是java文件
17.
服务器mycat代码如何在本地浏览器打开网页
①运行代码
②马上用IE浏览器打开例如http://192.168.0.102:9090/格式的网址即可
192.168.0.102为本机IP地址,9090为代码中服务端socket的端口号
程序运行结果窗口出现例如以下信息:
GET / HTTP/1.1 请求行 请求方式 /myweb/1.html 请求的资源路径 http协议版本
请求消息头,属性名:属性值
Accept: text/html, application/xhtml+xml, image/jxr, */*//可以接受的网页类型
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393
Accept-Encoding: gzip, deflate
Host: 192.168.0.102:9090
Connection: Keep-Alive
//空行
//应答体
18.
网络结构:
1.C/S client/server
特点:
该结构的软件,客户端和服务端都需要编写
开发成本较高,维护较为麻烦
好处:
客户端在本地可以分担一部分运算
2.B/S browser/server
特点:
该结构的软件,只开发服务端,不开发客户端,因为客户端直接由浏览器取代
开发成本相对低,维护更为简单
缺点:
所有运算都在服务器端进行
19.碰撞实验
当游戏设计中的人物移动过程中,遇到了障碍,应该不能通过障碍,此时我们就要考虑所有模型
之间的碰撞问题,也就是我们所说的碰撞实验
模型碰撞思想
1.人物在屏幕上显示,显示在哪里?程序怎么知道人物的位置?
2.什么是障碍?计算机如何知道树木就是障碍?羊不是障碍?
二维数组中的数据1代表障碍,0代表空地
我们设计数据2代表人物,人物的数据在原始的二维数组中是不存在的,因此我们把
人物添加到程序中时,必须把这个数据2放到二维数组中
3.当人物遇到障碍后,怎么办?障碍针对人物的位置不同,是否会对人物的移动产生影响
碰到障碍时不做任何事情,即在下列代码类似的加入到方向移动代码中
if(datas[wy][wx+1] == 1){//向着某一方向移动,加减一
//判断遇到障碍后不做任何事情
return;
}
碰撞模型设计
碰撞模型是通过数组中的数据进行检测的,不同数据碰撞检测不同
人物模型移动设计
人物模型移动是通过两个整数来模拟当前人物在数组中的位置
碰撞模型实现
对不可通过的数据进行判断,比如说树木对应得数据1,不可通过,那么就可以使用判断的方式提前结束移动操作
特殊碰撞实现
当人物遇到箱子怎么办?
20.
创建Java Web项目直接在other里选上Web Project,注意右上角打开Java Enterprise视图
同时,新建项目运行后 IE打开网址格式为
http://本地本机地址:8080/项目名称/
http://192.168.0.102:8080/Web.html/
21.myeclipse常用快捷键:
代码提示 Alt /
快速导包 ctrl shift o
代码修复 ctr1 1
单行注释 ctrl / 取消 再按一遍
多行注释 ctrl shift / 取消 ctrl shift \
删除行 ctrl d
代码的格式化 ctrl shift F 有缩进的效果。有时候不好使,点击source - format
查找 ctrl f
移动选中文本 alt 上或下
22.Myeclipse编译Java文件出现无法加载主类的问题:没有在bin文件下生成class文件
解决方法:project->properties->java build path->Libraries,将jar路径不正确的引用(不用的)remove了,然后Add Extenal JARs,重新添加jar包。
23.debug的调试模式(断点调试模式)
* 使用这种模式,调试程序(看到程序里面数据的变化)
* 使用debug第一步需要设置一个断点(让程序运行停止在这一行)
- 显示出来行号
- 双击左边,出现一个圆点,表示设置了一个断点
* 使用debug as 方式,运行程序
- 提示是否进入到调试页面,yes
- 在断点的那一行,有一个绿色条,表示程序停止在这一行,没有向下运行
* 可以让程序向下执行
- 使用 step over ,快捷键是F6(单步执行)
- resume F8:表示调试结束,直接向下运行
** 比如当前的断点之后还有断点,跳到下一个断点
** 如果当前断点后面没有断点,直接运行结束
* debug的另外一个用途
** 查看程序的源代码(如api函数)
** F7 step into:进入到源代码的方法
** step return:返回
24.jdk5.0新特性
jdk1.1 1.2 1.4 5.0 6.0 7.0 8.0
** 泛型、枚举、静态导入、自动拆装想、增强for、可变参数
** 反射
==== 泛型 ====
① 泛型的简介
* 为什么要使用泛型?
- 一般用在集合上
** 比如现在把一个字符串类型的值放入到集合里面,这个值放入到集合之后,失去本身的类型,只能是Object类型
这个时候,比如想要对这个值进行类型转换,很容易出现类型转换错误,可使用泛型来解决
* 在集合上如何使用泛型
- 常用集合 list set map
- 泛型语法 集合
- 在list上使用泛型
代码:
@Test
Public void testList(){
List
list.add("aaaa");
list.add("bbbb");
list.add("bbbb");
Iterator
while(it.hasNext){
System.out.println(it.next());
}
- 在Set上来使用泛型
Set
- 在Map上来使用泛型
key value
Map
* 在泛型里面写是一个对象,String 不能写基本的数据类型 比如int
** 应该写基本的数据类型对应的包装类
byte -- Byte
short -- Short
int -- Integer
long -- Long
float -- Float
double -- Double
char -- Character
boolean -- Boolean
② 泛型使用在方法上
* 定义一个数组,实现指定位置上的数组元素的交换
* 方法逻辑相同,只是数据类型不同,这个时候使用泛型方法
- 使用泛型方法 需要定义一个类型,使用大写字母 T 表示:任意的类型
写在返回值之前 eg .
表示定义了一个类型 这个类型是 T
public static
T temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
③ 泛型在类上的使用(了解)
* 在一个类上定义一个类型,这个类型可以在类里面直接使用
public class TestDemo
//可以在类里面直接使用T的类型
T aa;
public void test1(T bb){}
//写一个静态方法 在类上面定义的泛型,不能在静态方法里面使用
public static void test2(A cc){}
}
④ 泛型擦除
* 首先泛型只是出现在源代码阶段,当编译之后泛型就不存在了
==== 枚举 ====
① 什么是枚举
** 需要在一定的范围内取值,这个值只能是这个范围内中的任意一个
** 现实场景:交通信号灯,有三种颜色,但是每次只能亮三种颜色中的任意一个
** enum 枚举类型名称 {对象1,对象2,对象3;} (注意分号位置)
** 枚举的构造方法也是私有的
** 特殊枚举的操作
-- 在枚举类里面有构造方法
** 构造方法里面有参数,需要在每个实例上面都写参数
-- 在枚举类里面有抽象方法
** 在枚举的每个实例里面都重写这个抽象方法
② 枚举的api的操作
** name():返回枚举的名称
** ordinal():枚举的下标,下标从0开始
** valueOf(Class
** 还有两个方法,但是这两个方法不在api里面,编译的时候生成两个方法
- valueof(String name) 转换枚举对象
- values() 获取所有枚举对象数组
==== 静态导入(了解) ====
* 可以再代码里面,直接使用静态导入方式,导入静态方法或者常量
* import static XX.XX.xxx (import java.util.Arrays.sort)
** 比如现在实现一个计算器,在Math类里面
==== 自动拆装箱 ====
* 装箱
** 把基本的数据类型转换成对应的包装类
* 拆箱
** 把包装类转换成基本的数据类型
**
//自动装箱
Integer i = 10;
//自动拆箱
int m = i;
** 在jdk1.4里面实现拆装箱
//装箱
Integer m = new Integer(10);
//拆箱
int a = m.intValue();
** jdk是会向下兼容的
** 练习
public static void main(String[] args){
doSomething(10);
}
public static void doSomething(double m){
System.out.println("double...");
public static void doSomething(Integer a){
System.out.println("Integer...");
}
== 执行的结果是会调用 doSomething(double m)
== 首先在jdk1.4里面肯定调用这个方法,如果调用下面的方法,需要类型转换(10变成Integer要装箱,Integer与int有区别),但是jdk1.4不能自动拆装箱
== 由于jdk是向下兼容的,所有,在jdk1.4调用这个方法,在jdk5.0里面还是会调用这个方法
** 记住:八种基本的数据类型对应得包装类
* int -- Integer
* char -- Character
==== 增强for循环 ====
* 语法 for(遍历出来的值 : 要遍历的集合){}
* 数组:实现Iterable接口的集合可以使用增强for循环
* 在集合上使用增强for循环遍历
list set 实现了Iterable 接口,所以可以使用增强for循环
map没有实现Iterable接口,所以不能使用增强for循环
* 增强for循环出现目的:为了替代迭代器
** 增强for循环的底层实现就是迭代器
==== 可变参数 ====
* 可变参数可以应用在什么场景:
** 实现两个数的相加,实现三个数的相加,四个数的相加
-- 如果实现的多个方法,这些方法里面逻辑基本相同,唯一不同的是传递的参数的个数,可以使用可变参数
* 可变参数的定义方法: 数据类型...数组的名称 eg.(int...nums)
* 理解为一个数组,这个数组存储传递过来的参数
* 注意的地方
(1)可变参数需要写在方法的参数列表中,不能单独定义
(2)方法的参数列表中只能有一个可变参数
(3)方法的参数列表中的可变参数,必须放在参数的最后 - add(int a,int...num)
25.反射
① 反射的原理(***理解***)
* 应用在一些通用性比较高的代码中
* 后面学到的框架,大多数都是使用反射来实现的
* 在框架开发中,都是基于配置文件开发
** 在配置文件中配置了类,可以通过反射得到类中的所有内容,可以让类中的某个方法来执行
* 类中的所有内容:属性、没有参数的构造方法、有参数的构造方法、普通方法
* 画图分析反射的原理
* 首先需要把java文件保存到本地硬盘 .java
* 编译java文件,成.class文件
* 使用jvm,把class文件通过类加载器加载到内存中
* 万事万物都是对象,class文件在内存中使用class类表示
* 当使用反射时候,首先需要获取到Class类,得到了这个类之后,就可以得到class文件里面的所有内容
- 包含属性、构造方法、普通方法
* 属性通过一个类 Filed
* 构造方法通过一个类 Constructor
* 普通方法通过一个类 Method
②使用反射操作类里面的属性
* 首先获取到Class类
Class clazz1 = Person.class;
Class clazz2 = new Person().getClass();
Class clazz3 = Class.forName("cn.itcast.test09.Person");
* 比如:要对一个类进行实例化,可以new,不使用new,怎么获取?
//操作无参数的构造方法
//得到Class
Class c1 = Class.forName("cn.itcast.test.Person");
//得到Person的实例
Person p = (Person) c1.newInstance();
//设置值
p.setName("zhangsan");
System.out.println(p.getName());
//操作有参数的构造方法
//得到Class
Class c1 = Class.forName("cn.itcast.test.Person");
//使用有参数的构造方法
//c1.getConstructors();//获取所有的构造方法
//传递是有参数的构造方法里面参数类型,类型使用class形式传递
Constructor cs = c1.getConstructor(String class,String class);
//通过有参数的构造方法设置值
//通过有参数的构造方法创建Person实例
Person p1 = (Person) cs.newInstance("lisi","100");
System.out.println(p1.getId()+" "+p1.getName());
//操作name属性
try {
//得到Class类
Class c2 = Class.forName("cn.itcast.test.Person");
//得到name属性
//c2.getDeclaredFields();//表示得到所有的属性
//得到Person类的实例
Person p11 = (Person) c2.newInstance();
//通过这个方法得到属性,参数是属性的名称
Field f1 = c2.getDeclaredField("name");
//设置的是私有属性,设置true为可操作
f1.setAccessible(true);
//设置name值 set方法,两个参数:第一个参数是类的实例,第二个参数是设置的值
f1.set(p11,"wangwu");//相当于在p.name = "wangwu";
System.out.println(f1,get(p11));//相当于p.name
}catch(Exception e){
e.printStackTrace();
}
③ 使用反射操作普通方法
* 使用Method类表示普通方法
* 代码
//操作普通方法,比如操作 setName
//得到Class类
Class c4 = Class.forName("cn.itcast.test.Person");
//得到Person实例
Person p4 = (Person) c4.newInstance();
//得到普通方法
//c4.getDeclaredMethods();//得到所有的普通方法
//传递两个参数:第一个参数:方法名称,第二个方法:通过方法设置的值
Method m1 = c4.getDeclareMethod("setName",String.class);
//让setName方法执行,执行设置值
//使用invoke传递两个参数:第一个参数,person实例;第二个参数,设置的值
//执行了invoke方法之后,相当于,执行了setName方法,同时通过这个方法设置了一个值是niuqi
m1.invoke(p4,"niuqi");
System.out.println(p4.getName());
* //操作的私有的方法,需要设置值是true
* //m1.setAccessible(true);
* 当操作的方法是静态的方法时候,因为静态方法调用方式是 类名、方法名,不需要类的实例
* 使用反射操作静态方法的时候,也不需要实例
- 在invoke方法的第一个参数里面,写一个null
- m1.invoke(null,"niuqi");
26.Tomcat的安装及Myeclipse的配置
①下载免安装版zip文件,解压文件夹到一个路径中
②在Myeclipse的 Window - preference - Server Runtime Environments 中添加安装的tomcat相同的版本,再浏览选择①中所解压出的文件夹,添加确定。
③最后,在Myeclipse中下方的servers中空白处右键点New - servers -选择即可(若②完成时下方以及弹出相关tomcat则不需要进行③)
27.修复Myeclipse
打开安装包(E盘Baiduyun文件夹),选择repair,重新配置参考JavaWeb教程中day10的1
28.Mycelipse导入项目
File- import -General(Existing..) -Select root directory 中Browser浏览项目文件夹 -勾选下方Copy projects into workspace -finish即可
29.Myeclipse导入项目出现乱码
导入 一个JSP 项目,注释 出现 乱码!(一般是不会发生的!)
- 原因是因为,我的项目是 GBK编码, 目前只要是国内的项目,一般都是吧(哈哈 有点绝对了)
然而,我的MyEclispe 设置默认编码 的是UTF-8 !所以,在单击项目右键的时候,选择 属相栏,并没有 GBK项目
- 解决方法:
修改该项目的编码格式
修改单个工程的编码方式:右键点击项目--Preferences--Resource--将Text
file encoding改为GBK(下拉框没有GBK可直接输入框中)
30.Myeclipse中使用代码进行文件创建时,若路径只写如(1.txt),则会在项目代码目录下生成该文件