java基础知识点.docx
《java基础知识点.docx》由会员分享,可在线阅读,更多相关《java基础知识点.docx(21页珍藏版)》请在冰豆网上搜索。
java基础知识点
Java常用的API
Api:
应用程序接口,指的是系统中提供的大量的类及方法。
StringBuffer:
回顾:
String类的对象一旦声明则不可以改变。
String对象不适合于以下情况。
publicclassAPIDemo01
{
publicstaticvoidmain(Stringargs[])
{
Stringstr="";
for(inti=0;i<20;i++)
{
str+=i;
}
System.out.println(str);
}
};
StringBuffer也是一个字符串对象,但是,此对象种的内容可以改变。
只是代码的形式不同,StringBuffer必须先实例化。
StringBuffer可以改变,String不可以改变。
包装类:
IO操作时字符串变为整型:
Integer。
在java中提倡一种思想,一切皆对象,java中有八种数据类型。
此处以前讲过。
Runtime类
运行时类—使用此类可以调用本机上的程序。
Runtime类中没有任何一个构造方法,则外部无法实例化。
因为在类中将构造方法私有化了。
Random类
表示一个随机数的类,例如,产生一个不大于100的10个随机数。
位于java.util包下。
取得时间的类
Date、Calendar(此类可以将时间精确到毫秒)
Calendar是一个抽象类,要想实例化此类则需要子类在jdk中已经明确给出了操作此类的方法。
有时候希望可以对格式进行转换
原格式1:
2009-11-1716:
19:
33
转换的格式:
2009年11月17日16时19分33秒
应该用几步完成以上操作呢?
1、从原格式中丢弃格式取出具体的时间数字。
2、准备一个新的格式。
3、将原格式中的时间数字放到新的格式中去。
SimpleDateFormat类,此类在java.text包下。
以上介绍的只是一些基本的常用类。
Jdk开发中经常要使用到的一些小功能或小工具。
Java高级特性
今天的任务
1、hashCode方法作用介绍。
2、对象克隆。
3、比较器。
4、Class类。
hashCode—哈希玛。
Map—hashtable,hashMap。
实际上每一个对象都有一个hashCode。
如果只复写hashCode方法根本不会起作用,还需要同时复写equals方法。
对象克隆
就是对象的复制。
IO序列化:
Serializable—可以序列化。
要完成克隆的类必须具备以下2种条件:
1、类必须实现Cloneable接口,表示可以被克隆。
2、类必须复写Object类中的clone方法。
比较器
Arrays—专门用于数组排序。
可以对任意数据类型排序。
例题:
给出一个Person类里面包含姓名、年龄、成绩,声明5个Person对象的对象数组,要求对数组中的内容进行排序,排序规则如下:
按成绩由高到低排序,如果成绩一样,就按照年龄由高到低排序。
比较器除了在Arrays类的排序外还可以用在TreeSet上,实际上TreeSet也需要比较器支持。
Class类
类—对象。
我们希望由对象能够知道其所属的类是哪个。
Class能够动态的为类实例化。
Class类本身没有任何构造方法。
总结出Java中对象实例化的途径:
1、直接用new,代码比较直观,但是程序会出现耦合度。
2、程序出现了接口,如果一个接口的子类直接通过new实例化会造成程序的耦合,所以,使用工厂进行解耦和操作。
3、对象的克隆,将对象拷贝一份,但是,此种方法需要在子类中复写clone方法。
4、Class类,通过Class类来实例化一个对象,通过字符串操作完成。
关于Class类只需要重点掌握实例化对象的操作。
Java网络编程
Java网络编程
C/S程序应用:
客户/服务器;msn,一个客户端,客户端打开之后连接到服务器上。
B/S程序应用:
浏览器/服务器;所有的代码直接放在服务期上即可—jsp。
程序分为2种:
基于tcp协议:
Socket,可靠的服务:
a—b;
基于udp协议:
不可靠,短信功能。
如果要编写一个tcp程序需要java的2个包支持。
J.*:
主要提供网络支持。
|-ServerSocket类:
主要用来写服务器端程序。
|-Socket类:
客户端程序。
Java.io.*:
传递信息流。
客户端就2个功能
1、建立Socket。
2、接收输入的命令(输入流)—网络上传输的程序靠的是字节流。
在jdk中也准备了2个专门用于实现udp的类:
DatagramSocket和DatagramPacket。
Java多线程
中断线程的运行:
当一个线程运行时候,另一个线程可以调用对应的Thread对象的Interrupt()方法来中断它。
Publicvoidinterrupt();
查看线程的中断状态:
可以在Thread对象上调用isInterrupted方法来检查任何线程的中断状态。
PublicBooleanisInterrupted()
线程如果中断之后再休眠,则会清除中断标志。
多线程问题—资源的协调
对共享对象的访问必须同步,叫做条件变量。
Java语言可以通过监视器使用条件变量实现线程的同步。
监视器阻止2个线程同时访问同一个条件变量,它的作用如同锁一样作用在数据上。
线程1进入卖票方法,获得监视器,也就是加锁;当线程1的方法执行完毕返回时,释放监视器,也就是开锁。
线程2的卖票方法才能进入。
用Synchronized来标识的区域或方法即为监视器监视的部分。
一个类或一个对象由一个监视器,如果某一个程序中有2个方法使用了Synchronized标识,则它们一直在一个监视器管理之下。
一般情况下,只在方法的层次上使用关键区,也就是Synchronized关键字。
同步操作就是在方法之中加入了一个Synchronized关键字,表示此方法为同步方法。
提供了Synchronized关键字之外的第二种使用,同步代码块
同步代码块就是使用了Synchronized关键字括起来的代码表示同步代码块,同步代码块需要一个同步对象,实际上就是用{}括起来的代码。
同步代码块—在java中使用Synchronized关键字进行同步
Synchronized(对象)
{
同步代码
}
应该是对当前操作的线程进行同步,所以此操作应该使用this,为this进行同步。
上次回顾:
多线程同步问题(synchronized)
在多个线程中操作同一个资源的时候产生的问题
同步可以通过两种方式实现
同步方法
同步代码块
同步会产生一个问题—死锁。
死锁就是在多线程编程中由于处理不当而造成程序停止运行的一种状态。
同步的问题—线程死锁的问题
死锁一般而言,是在程序运行中发生的一种状态,所以此处只是简单模拟一下。
此处有2个线程—线程1是笔记本,线程2是钢笔。
线程1执行—把钢笔给我,我才能给你笔记本。
线程2执行—把笔记本给我,我才能把钢笔给你。
死锁大家只需要了解其产生的根本原因即可。
同步有一个经典的范例—生产者和消费者
线程之间通信
一个线程向数据存储空间添加数据(生产者),另一个线程从数据存储空间中取走数据(消费者)。
这个程序有2种例外需要考虑:
1、假设生产者线程刚向数据存储空间添加了一个人的姓名,还没有加入这个人的性别,cpu就切换到消费者线程,消费者线程把这个人的姓名和上一个人的性别联系到了一起。
2、生产者放了若干次的数据,消费者才开始取数据,或者是,消费者取完一个数据后,还没等到生产者放入新的数据,又重复取出已取过的数据。
可能会出现的2个问题:
1、生产者比消费者快时,消费者会漏掉一些数据没有取到。
2、消费者比生产者快时,消费者取相同的数据。
工厂模式综合讲解
工厂设计模式
Class类的反射。
IO操作。
回顾一下到底什么是工厂设计及好处?
1、对于刚才的工厂设计存在以下问题
如果现在客户main要求既可以使用Apple对象,也可以使用Orange对象,则无法通过工厂完成。
2、对于第二种实现存在以下问题
a)如果输入参数错误,则会出现空指向异常。
b)如果在子类中扩充了一个子类,则要修改工厂(工厂中如果没有子类的判断,则无法使用这个子类)。
3、通过第三种实现去解决第二种实现中修改工厂的操作。
解决了工厂由于增加了子类需要修改的问题。
一个新的问题产生了,在项目中可能有几十个类同时实现了同一个接口,那么此时用户如何知道已有的接口子类呢?
代号—子类的包.类名称(key--value)。
要有一个文件列表,给用户列出全部的代码—子类的映射。
4、第四种实现解决了用户无法知道全部子类的问题,同时通过了Properties保存了全部的子类信息,之后通过代码进行操作。
程序中依然存在问题,如果程序现在扩充了一个子类,则需要修改设置的属性。
解决的方法:
通过文件保存Properties中的内容,以后,修改文件即可,而不用去修改类本身。
总结:
可能有大部分人认为工厂设计过于复杂,而且没有用处,具体的用法需要通过大量的训练才能够彻底掌握工厂设计模式的好处。
如果一个接口需要一个工厂的话,那么如果有100个接口,则会出现100个工厂,程序的维护又会很困难。
Java接口与类集综合应用
接口与类集综合应用
List、Set、Map。
看以下一种情况。
图书大厦里可以放很多种的书。
儿童书。
电脑书。
建筑书。
要求实现以下一种功能:
模拟图书大厦,图书大厦里可以存放多种书目,而且可以进行添加操作、删除操作、查询操作。
一个类集中可以加入多个对象,对应于儿童书、电脑书。
图书大厦-->List-->书的接口<--各种书。
Java类集应用
类集应用
例如:
以下一种关系,一个人拥有多个Email。
分析:
1、完成此功能需要多少个类?
a)人—类;
b)Email—类;
c)多个?
如何体现?
在Person类中加入一个集合,此集合中保存多个Email地址。
一对多的关系,一个人拥有多个Email,是数据库中一种一对多的关系。
多对多的关系,一个学生可以选多门课程,一个课程可同时被多个学生选择。
文件操作
文件操作
本章目标
1、掌握文件类(File类)的使用
2、掌握IO包中流的基本应用
3、了解字符编码问题
4、掌握对象序列化
文件类分为三大类
1、file类,文件操作类
2、字节操作类
3、字符操作类
File类:
File类是io包中唯一代表磁盘文件本身的对象,File类定义了一些与平台无关的方法来操作文件,通过调用File类提供的各种方法,能够创建、删除、重命名文件,判断文件的读写权限是否存在,设置和查询文件的最近修改时间。
直接与文件操作有关的类。
在f盘上创建一个demo.txt文件。
Importjava.io.*;
PublicclassIODemo01
{
publicstaticvoidmain(Stringargs[])
{
Filef=newFile(“f:
\\demo.txt”);
Try
{
f.createNewFile();
}
Catch(Exceptione)
{
System.out.println(e);
}
}
}
文件操作时会进行判断,如果文件已经存在,则不会重新创建。
能不能通过程序直接判断文件是否存在呢?
/是可以的
Importjava.io.*;
PublicclassIODemo02
{
Publicstaticvoidmain(Stringargs[])
{
Filef=newFile(f:
\\demo.txt);
If(f.exists())
{
System.out.println(“文件已经存在”);
}
Else
{
System.out.println(“文件不存在”);
}
}
}
操作:
能否完成以下操作
如果文件存在则删除,如果文件不存在则创建。
Importjava.io.*;
PublicclassIODemo03
{
Publicstaticvoidmain(Stringargs[])
{
Filef=newFile(f:
\\demo.txt);
If(f.exists())
{
f.delete();
}
Else
{
f.createNewFile();
}
}
}
已经明确知道了可以通过File类找到全部文件
问题:
能不能使用File类去取出d盘下的全部文件呢?
是可以的
递归:
一个方法自己调用自己的情况。
Importjava.io.*;
PublicclassIODemo04
{
Publicstaticvoidmain(Stringargs[])
{
Loop(“d:
\\”);
}
Publicstaticvoidloop(Stringdir)
{
Filef=newFile(dir);
Stringstr[]=null;
If(f.isDirectory())
{
Str=f.list();
For(inti=0;i {
Loop(dir+”\\”+str[i]);
}
}
Else
{
System.out.println(dir);
}
}
}
下面我们讲解输入输出方法
什么是数据流?
数据流是指所有的数据通信管道。
在java中有关流的操作使用java.io.*.
出于安全的考虑,小应用不能实现文件io流。
读写过程
读:
打开一个流,如果有信息,则读入,最后,关闭流。
写:
打开一个流,如果有信息,则写入,最后,关闭流。
打个比方:
读一本书的过程
1、要找到这本书。
2、要从书中读取文字过渡到大脑之中。
3、书读完之后要将书放下
下面我们讲解RandomAccessFile
1、RandomAccessFile类支持”随机访问”方式,可以跳转到文件的任意位置处读写数据。
2、RandomAccessFile对象类有个位置指示器,指向当前读写处的位置,当读写了n个字节后,文件指示器指向这n个字节的下一个字节处,该类仅限于操作文件。
3、newRandomAccessFile(f,”rw”);//读写方式
4、newRandomAccessFile(f,”r”);//只读方式
5、当程序需要以读写的方式打开一个文件时,如果这个文件不存在,程序会创建。
6、支持随机文件操作的方法。
7、readXXX()或writeXXX()。
8、skipBytes()将指针向下移动若干字节。
9、seek()将指针调到所需的位置。
10、getFilePointer()返回指针当前位置。
11、length()返回文件长度。
12、利用seek(longpos)方法查找随机文件中的信息,例,把若干个32位的整数写到一个名为temp.dat的文件中,然后利用seek方法,以相反的顺序再读取这些数据。
Importjava.io.*;
PublicclassIODemo07
{
Publicstaticvoidmain(Stringargs[])
{
//随机读取
RandomAccessFileraf1=newRandomAccessFile(“f:
\\demo.txt”,”rw”);
//随机读取有一个限制,就是说如果要进行操作,则必须指定好数据的存取长度
//保存姓名(8位字符串)和年龄(int4)
Stringname=“zhangsan”;
Intage=20;
Raf1.write(name.getBytes());
Raf1.writeInt(age);
Name=“lisi”;
Age=30;
Raf1.write(name.getBytes());
Raf1.writeInt(age);
Name=“wangwu”:
Age=33;
Raf1.write(name.getBytes());
Raf1.writeInt(age);
Raf1.close();
RandomAccessFileraf2=newRandomAccessFile(“f:
\\demo.txt”,”r”);
//读取第二个人的数据。
raf2.skipBytes(12);
byteb[]=newbyte[8];
raf2.read(b);
intage2=raf2.readInt();
System.out.println(newString(b)+”-->”+age2);
}
}
File与文件有关
RandomAccessFile类与文件内容有关,但是,此类有一个缺点,就是说如果要跳转,则需要数据的保存长度。
字节流与字符流
输入字节流:
InputStream
输入字符流:
Reader
输出字节流:
OutputStream
输入字符流:
Writer
我们以OutputStream类来讲解
OutputStream类是一个抽象类,在java中上述的四种类都是抽象类。
抽象类必须通过子类来实例化。
举例:
现在希望向文件中打印一句话:
”hello,verybody”
FileOutputStream为OutputStream实例化
InputStream与OutputStream
InputStream与OutputStream主要用来对字节流进行操作。
主要操作方式:
1、用File类找到一个文件。
2、用File类的对象去实例化InputStream或OutputStream的子类对象。
3、对文件进行读/写操作。
4、关闭文件。
既然可以从程序中向文件中写入内容,那能否从文件中读出内容呢?
肯定是可以滴
InputStream-->FileInputStream
InputStream与OutputStream所操作的都是字节操作-->所有的数据都要通过byte数组操作。
在java中提供了另外的两套类,此类用于操作字符:
Reader,Writer。
字符流输出时如果不关闭则无法将内容写入到文件。
根本原因是如果字符流不关闭,则内存中的数据不会强制性的输出到文件,即,字符流操作中使用了缓存,在关闭时会强制性的情况缓存,也可以使用flush方法手工清空缓存。
字符流用到了缓存,而字节流没有用到缓存。
管道流:
线程间的通信可以用管道流。
importjava.io.*;
//定义一个发送者
classSendDemoimplementsRunnable
{
privatePipedOutputStreamout;
publicSendDemo()
{
out=newPipedOutputStream();
}
publicPipedOutputStreamgetOut()
{
returnthis.out;
}
publicvoidrun()
{
Stringstr="HelloLuoHui";
try
{
out.write(str.getBytes());
out.close();
}
catch(Exceptione)
{
}
System.out.println("SendDemo-->发送的内容:
"+str);
}
};
classReceDemoimplementsRunnable
{
privatePipedInputStreamin=null;
publicReceDemo()
{
in=newPipedInputStream();
}
publicPipedInputStreamgetIn()
{
returnthis.in;
}
publicvoidrun()
{
byteb[]=newbyte[1024];
intlen=0;
try
{
len=in.read(b);
in.close();
}
catch(Exceptione)
{
System.out.println(e);
}
System.out.println("ReceDemo-->收到的内容是:
"+newString(b,0,len));
}
};
publicclassIODemo12
{
publicstaticvoidmain(Stringargs[])
{
SendDemosd=newSendDemo();
ReceDemord=newReceDemo();
Threadsend=newThread(sd);
Threadrece=newThread(rd);
//将两个线程进行连接
PipedOutputStreamout=sd.getOut();
PipedInputStreamin=rd.getIn();
//将输出连接到输入
try
{
out.connect(in);
}
catch(Exceptione)
{
}
send.start();
rece.start();
}
};
ByteArrayInpu