这两个星期讲了很多内容,由于各种原因没来得及总结,我知道其实这些都不是理由,只要合理的安排好时间,任何有意义的事情绝对是有必要而且能够完成的。
人都是懒惰的动物,都是健忘的动物。时间长了,曾经发过的誓,曾经许下的诺言,突然就没有印象了。所以最好的办法是,每天都好好的提醒下自己,自己来学习的目的是为何的,自己曾经是多么的落魄过,是不是还想和以前一样。
多说也无益。整理下前面讲过的内容吧。
这两个星期主要讲的是java的高级编程,也无非是运用API来深入的学习java。
1. GUI
AWT容器:重量级组件,依赖本地平台的窗口系统
Swing组件:轻量级组件,完全用JAVA写成,大多都以J开头,awt中有与之对应的组件
Frame(框架)能独立存在的顶层窗口容器
Dialog(对话框)依赖于某个父组件而存在的顶层窗口容器
Panel(面板)嵌入到其它容器内部的容器
Applet(小程序)嵌入到其它环境(如:浏览器)中运行的java小程序
基本步骤:
① 定义一个窗口Jframe及各组件。
② 构造方法里面初始化各组件。
③ Init()方法里边将各组件加到窗口或面板中,并按照一定得布局。Jframe的默认布局是BorderLayout,Jpanel的默认布局是FlowLayout。
④ showMe()方法中设置窗口大小,可见性及关闭方式。
Jframe.EXIT_ON_CLOSE,Jframe.DO_NOTHING_ON_CLOSE
⑤ 设置addEventHandle()方法中各个组件事件源的监听器
⑥ 主方法中new个对象调用方法。
事件处理的两种方式:
1.用内部类实现
// 为Button 注册ActionEvent 的监听器
button.addActionListener(new ActionLIstener(){//定义一个内部类
public void actionPerformed(ActionEvent e){
// 相关操作代码
}
});
2.用容器类实现监听接口
public class FrameCounter extends Frame implements ActionListener{
private Button button = new Button(“1”);
public FrameCounter(String title){
super(title);
// 把FrameCounter 本身的实例注册为Button 的监听器
button.addActionListener(this);
}
}
2. 多线程并发
理解这副图就可以理解一切。
生产者-消费者例子中,因为生产者和消费者sleep的时间不一样,那么就一定有一段时间内是生产者占优,那么生产的速度就很快,那如果是data增加很快,则store不能存放,那么如果继续添加的话,必须先wait,wait的时候生产者的线程就进入到等待池里边,同时释放锁,则消费者线程拿到钥匙,进入到Runable状态,等到os的调度,进入到Running状态,消耗掉数据。等消费者线程结束以后,然后调用notifyAll方法唤醒消费者线程。继续运行。同样的原理在仓库里面没东西的时候就不能消费了,消费者线程需要wait。
线程类的两种方法:
(1)继承Thread 类:
1、extends Thead
2、重写run()方法
3、new 本类.start();
好处:编写简单,可读性好
(2)实现Runnable接口
1、implements Runnable
2、重写run()方法
3、new 本类,new Thread(本类对象)
4、Thread对象.start();
好处:保留了类继承,代码和逻辑分离,便于实现多线程。
线程中几个重要的方法:
Thread.currentThread()取当前线程(实现接口方式有时用这个)
sleep():暂停线程,本线程不会抢,除非sleep 运行完,这个是静态方法。
自己让出CPU,其它的来抢。
yield():暂停线程,给本类或>=本类优先级的。只给优先级高的让,
一般优先级低的抢不到
join():让本线程加入主线程。在线程内部、程序依然是顺序执行的,
乱序体现在不同线程。
tj.start();
tj.join();要按这个顺序执行,若把join放在前面是无意义的。
3. I/O系统
基本步骤:
① 先判断是读还是写,是文本的字符的/还是二进制字节的,然后看数据的来源和目的地
② new个对象,将参数传进去,选择哪种节点流和包装流
③ 循环遍历,将之读出,或者写入。
④ 处理异常,在finally中关闭流
二.对象的序列化与反序列化
对象的序列化是指把对象写到一个输出流中,对象的反序列化是指从一个输
入流中读取一个对象。Java 语言要求只有实现了java.io.Serializable 接口的类的对象才能被序列化及饭序列化。例如:String, 包装类,Date 类等都实现了
Serializable 接口。
对象的序列化包括以下步骤:
(可以实现对象的深拷贝)序列化版本标示符SerialVersionUID
(1) 创建一个对象输出流,它可以包装一个其他类型的输出流,比如文件
输出流。
ObjectOutputStream out = new ObjectOutputStream(new
FileOutputSteam(“D://readme.txt”));
(2) 通过对象输出流的writeObject()方法写对象。
out.writeObject(“hello”);
out.writeObject(new Date());
out.writeObject(new Customer(“Andy Bai”,27));
以上代码把一个String 对象和一个Date 象都保存到objectFile.obj 文件中,在
这个文件中保存了这两个对象的序列化形式的数据,这种文件无法用普通的文本
编辑器打开,这种文件里的数据只有ObjectInputStream 类才能识别它,并且能对它进行反序列化。
对象的反序列化包括以下步骤:
(1) 创建一个对象输入流,它可以包装一个其他类型的输入流,比如文
件输入流。
ObjectInputStream out = new ObjectInputStream(new
FileInputStream(“D;//out.txt”));
(2) 通过对象输入流的readObject()方法读取对象
String obj1 = (String) out.readObject();
Date obj2 = (Date)out.readObject();
Customer obj3 = (Customer)out.readObject();
为了能读出正确的数据,必须保证向对象输出流写对象的顺序与从对象输入
流读对象的顺序一致。
通常对象中的所有属性都会被序列化,对于一些比较敏感的信息比如用户密
码,一旦序列化后,人们就可以窃取,出去安全考虑,应该禁止对这种属性
的序列化,解决办法是把这种属性用transient 修饰,它就不会参与序列化及
反序列化过程。
4. Net-Work
TCP:
服务器端基本步骤:
① 先声明ServerSocket ss=null; Socket s=null;PrintWriter pw=null;
② 初始化ss=new ServerSocket(8888);(创建一个套接字)
S=ss.accept();(接受来自客户端的请求)
Pw=new PrintWriter(s.getOutputStream());写出的地方
Pw.println(new Date().toString());写出的内容
同时捕获异常,并且释放资源。
客户端基本步骤:
public static void main(String[] args) {
Socket s = null;
BufferedReader br = null;
try {
// 第一步:创建一个套接字
s = new Socket("127.0.0.1", 9898);
// 第二步:从套接字中获得InputStream
InputStream is = s.getInputStream();
// 第三步:把InputStream封装成BufferedReader
br = new BufferedReader(new InputStreamReader(is));
// 第四步:从br中读取数据
String str = br.readLine();
System.out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 第五步:释放资源,注意关闭顺序
if (br != null)
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
if (s != null)
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}