Java基础知识(九)
原创
Bighead08292018-05-24 17:06:31©著作权
阅读数
268
©著作权归作者所有:来自51CTO博客作者Bighead0829的原创作品,如需转载,请注明出处,否则将追究法律责任
https://blog.51cto.com/u_13678728/2119940
**一、计算机在Eclipse中存储中文方式**
(1)平台默认编码集:GBK,一个中文对应两个字节。
(2)第一个字节:一定是负数;第二个字节:一般是负数,可能也会是正数,不影响结果。
(3)例如:
```
public class Demo {
public static void main(String[] args) {
//定义一个字符串
String str = "大脑袋" ;
//转成字节数组
byte[] bys = str.getBytes() ;
System.out.println(Arrays.toString(bys));
}
}
```
结果:
![](https://s4.51cto.com/images/blog/201805/24/df396cdc7e290c18c94c9e2f6e6ca06c.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
**二、解码/编码**
1、编码和解码时前后编码格式必须一致。
2、编码
(1)转换过程:字符串→字节→二进制数据
(2)编码方法:
A、public byte[] getBytes() :平台默认编码集编码(默认的是Gbk)。
B、public byte[] getBytes(Charset charset) ;指定格式编码。
3、解码
(1)转换过程:二进制数据→十进制数据→字节→字符串
(2)解码方法:
A、public String(byte[] bytes)使用平台默认编码集解码(gbk)。
B、public String(byte[] bytes,Charset charset):用指定的编码格式解码。
**三、字节缓冲流(高效字节流)**
1、字节缓冲输入流BufferedInputStream
(1)构造方法
A、public BufferedInputStream(InputStream in):默认缓冲区大小构造缓冲输入流对象。
B、public BufferedInputStream(InputStream in,int size):指定缓冲区大小构造缓冲输入流对象。
(2)读取方式
A、public int read()一次读取一个字节。
B、public int read(byte[] b,int off,int len)一次读取字节数组的一部分。
(3)例如一次读取一个字节数组:
```
public class BufferedInputStreamDemo {
public static void main(String[] args) throws FileNotFoundException,IOException{
//创建字符缓冲输入流对象
BufferedInputStream bis=new BufferedInputStream(
new FileInputStream("a.txt"));
//一次读取一个字节数组
byte[] bys=new byte[1024];
int len=0;
while((len=bis.read(bys))!=-1) {
//创建一个String对象,将读取到的字节数组转换为String类型输出
System.out.println(new String(bys,0,len));
}
//关闭流,释放资源
bis.close();
}
}
```
2、字符缓冲输出流
(1)构造方式
A、public BufferedOutputStream(OutputStream out)采用默认缓冲区大小构造一个字节缓冲输出流对象。
B、public BufferedOutputStream(OutputStream out,int size)指定size缓冲区大小构造缓冲输出流对象。
(2)写数据方式
A、public int write(int by)一次写一个字节。
B、public int read(byte[] b,int off,int len)一次写字节数组的一部分。
(3)刷新功能:void flush() 刷新缓冲区的流。
(4)例如一次写字节数组的一部分:
```
public class BufferedOutputStreamDemo {
public static void main(String[] args) throws FileNotFoundException,IOException{
//创建字符缓冲输出流对象
BufferedOutputStream bos=new BufferedOutputStream(
new FileOutputStream("a.txt"));
//一次写字节数组的一部分
bos.write("大脑袋".getBytes());
//关闭流,释放资源
bos.close();
}
}
```
3、字符缓冲流复制文件(以一次复制一个字节数组为例)
```
public class BufferedCopy {
public static void main(String[] args) throws Exception{
//封装
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("b.txt"));
//一次复制一个字节数组
byte[] bys=new byte[1024];
int len=0;
while((len=bis.read(bys))!=-1) {//读取数据
//写数据
bos.write(bys,0,len);
//刷新
bos.flush();
}
//关闭资源
bos.close();
bis.close();
}
}
```
5、(面试题)字节缓冲流的构造方法为什么不能直接传递路径/文件?
解:缓冲流只是在底层内部提供一个缓冲区的数组,底层实现文件的复制/读取/写入这些操作都依赖于基本流对象。
6、常见异常:IllegalArgumentException指定缓冲区大小越界异常。
**四、字符流(解决中文乱码问题)**
1、字符输入流Reader
(1)抽象类,创建对象时使用其子类。
(2)子类:
A、字符转换输入流:InputStreamReader
B、便捷类:FileReader
(3)字符转换输入流构造方法
A、public InputStreamReader(InputStream in) :默认编码方式构造字符转换输入流。
B、public InputStreamReader(InputStream in,Charset cs)指定编码方式构造字符转换输入流。
(4)字符输入流读取数据方式
A、int read(char[] chs)一次读取一个字符数组。
B、int read()一次读取单个字符。
3、字符输出流Writer
(1)抽象类,创建对象时使用其子类。
(2)子类:
A、字符转换输出流:OutputStreamWriter
B、便捷类:FileWriter
(3)字符转换输入流构造方法
A、public OutputStreamWriter(OutputStream out):使用默认的编码格式构造一个字符转换输出流对象。
B、public OutputStreamWriter(OutputStream out, Charset cs):使用指定编码格式构造一个字符转换输出流对象。
(4)字符输出流写数据方式
A、public void write(int c)一次写单个字符 。
B、public void write(char[] cbuf)一次写字符数组。
C、public abstract void write(char[] cbuf, int off, int len)一次写字符数组的一部分。
D、public void write(String str)一次写一个字符串。
E、public void write(String str,int off, int len)一次写字符串的一部分。
4、(面试题)flush和close方法的区别:
(1)close关闭该流,关闭该流对象以及和它关联的资源文件,关闭之后,不能再对流对象进行操作了,否则会有异常。
(2)flush刷新该流,为了防止一些文件(图片文件/音频文件)缺失或者没有加载到流对象中。刷新了该流,还是可以流对象进行操作。
5、采用字符流复制文件(一次复制一个字符数组)
```
public class Copy {
public static void main(String[] args) throws Exception{
//封装
FileReader fr=new FileReader("e:\\BR苏苏不酥\\大脑袋.txt");
FileWriter fw=new FileWriter("e:\\BR苏苏不酥\\Bighead.txt");
//一次复制一个字符数组
char[] chs=new char[1024];
int len=0;
while((len=fr.read(chs))!=0) {
fw.write(chs,0,len);
//刷新流
fw.flush();
}
//关闭资源
fw.close();
fr.close();
}
}
```
**五、字符缓冲流(更高效)**
1、字符缓冲输入流BufferedReader
(1)构造方法
A、public BufferedReader(Reader in)使用默认大小输入缓冲区创建一个缓冲字符输入流。
B、public BufferedReader(Reader in, int sz)使用指定大小输入缓冲区创建一个缓冲字符输入流。
(2)特有功能:public String readLine()一次读取一行。
2、字符缓冲输出流BufferedWrier
(1)文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
(2)构造方法
A、public BufferedWriter(Writer out) 默认缓冲区大小构造字符缓冲输出流对象。
B、public BufferedWriter(Writer out,int size):指定缓冲区大小构造字符缓冲输出流对象。
(3)特有功能:public void newLine()写入一个行的分隔符号(换行)。
3、使用字符缓冲流复制文件(以一次复制一行为例)
```
public class CopyTeyou {
public static void main(String[] args) throws Exception{
//封装文件
BufferedReader br=new BufferedReader(new FileReader("e:\\BR苏苏不酥\\大脑袋.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("e:\\BR苏苏不酥\\Bighead.txt"));
//一次复制一行
String line=null;
while((line=br.readLine())!=null) {
bw.write(line);
//写入一个行的分隔符号
bw.newLine();
//刷新流
bw.flush();
}
//关闭流,释放资源
br.close();
bw.close();
}
}
```
4、将集合中的内容存储到文本文件中
```
public class ArrayListToTxt {
public static void main(String[] args) throws Exception{
//创建集合对象
ArrayListal=new ArrayList();
//添加元素
al.add("Bighead");
al.add("0829");
//创建字符缓冲输出流对象
BufferedWriter bw=new BufferedWriter(new FileWriter("e:\\BR苏苏不酥\\Bighead.txt"));
//遍历集合
for(String s:al) {
//将遍历到的元素写入文本文件中
bw.write(s);
bw.newLine();
//刷新
bw.flush();
}
//释放资源
bw.close();
}
}
```
5、将文本文件中的内容添加到集合中
```
public class TxtToArrayList {
public static void main(String[] args) throws Exception{
//创建字符缓冲输入流对象
BufferedReader br=new BufferedReader (new FileReader ("e:\\BR苏苏不酥\\Bighead.txt"));
//创建集合对象
ArrayListal=new ArrayList();
//读取文本文件中的内容,一次读取一行
String line=null;
while((line=br.readLine())!=null) {
//将读取到的内容添加集合中
al.add(line);
}
//遍历集合,输出元素
for(String s:al) {
System.out.println(s);
}
}
}
```
**六、内存操作流**
1、概述:适用于临时存储文件。一个程序结束后,这些程序的变量会从内存消失内存操作流就是对马上消失的这些数据进行读取写入。
2、内存操作输入流byteArrayInputStream
构造方法:ByteArrayInputStream(byte[] buf)
3、内存操作输出流byteArrayOutputStream
构造方法:ByteArrayOutputStream()
4、例如:
```
public class ByteArrayOutputStreamDemo {
public static void main(String[] args) throws IOException{
//创建内存输出流对象
ByteArrayOutputStream baos=new ByteArrayOutputStream();
//写数据
baos.write("Bighead0829".getBytes());
//创建字节数组,将写入的内容转化为字节数组并存入该字节数组中
byte[] bys=baos.toByteArray();
//创建内存操作输入流对象
ByteArrayInputStream bais=new ByteArrayInputStream(bys);
//读取内存中的数据并将其显示在控制台上,一次读取一个字节
int by=0;
while((by=bais.read())!=-1) {
//将读取到的字节转换为字符类型,并在控制台输出
System.out.print((char)by);
}
}
}
```
**七、数据流**
1、概述:针对Java基本类型的数据进行读写操作。
2、数据输入流DataInputStream
3、数据输出流DataOutputStream
4、例如:
p```
ublic static void main(String[] args) throws Exception{
//创建数据输出流对象
DataOutputStream dos = new DataOutputStream(
new FileOutputStream("e:\\西部开源\\作业\\课后练习\\博客\\18\\数据流.txt"));
//创建数据输入流对象
DataInputStream dis = new DataInputStream(
new FileInputStream("e:\\西部开源\\作业\\课后练习\\博客\\18\\数据流.txt"));
//写数据
dos.writeInt(10);
dos.writeShort(8);
dos.writeLong(29);
dos.writeFloat(5.23F);
dos.writeDouble(11.11);
dos.writeBoolean(true);
dos.writeByte(315);
dos.writeChar('l');
//刷新流
dos.flush();
//读数据
int i=dis.readInt();
short s=dis.readShort();
double d=dis.readDouble();
long l=dis.readLong();
char c=dis.readChar();
float f=dis.readFloat();
boolean flag=dis.readBoolean();
byte b=dis.readByte();
//关闭流,释放资源
dis.close();
dos.flush();
//输出
System.out.println("int:"+i+"\n"+"short:"+s+"\n"+"double:"+d+"\n"+"long:"+l
+"\n"+"char:"+c+"\n"+"float:"+f+"\n"+"boolean:"+flag+"\n"+"byte:"+b);
}
```
**八、打印流**
1、概述:PrintWriter,打印流,属于输出流。
2、特点:
(1)只能写数据(只能针对目的地文件进行操作),不能读数据(不能针对源文件进行操作)。
(2)可以针对文件直接进行操作。若一个类中的构造方法里面有File对象或者String类型数据,则这个类可以对文本文件直接操作。
(3)自动刷新功能:PrintWriter(OutputStream out/Writer out,boolean autoflush),第二个参数如果是true ,表示启动自动刷新功能。
(4)打印的方法print(XXX x)/println(XXX xx)
3、分类:
(1)字符打印流(针对文本进行操作PrintWriter)
(2)字节打印流(printStream 和标准输出流有关系 System.out;)
**九、合并流**
1、概述:SequenceInputStream 表示其他输入流的逻辑串联(合并流)。
2、构造方法 :
(1)public SequenceInputStream(InputStream s1, InputStream s2)
(2)public SequenceInputStream(Enumeration e)
3、例如:
```
public static void main(String[] args) throws Exception{
//封装源文件
InputStream is1=new FileInputStream("e:\\西部开源\\作业\\课后练习\\博客\\18\\合并流a.txt");
InputStream is2=new FileInputStream("e:\\西部开源\\作业\\课后练习\\博客\\18\\合并流b.txt");
//创建合并流对象,将is1和is2合并
SequenceInputStream sis=new SequenceInputStream(is1,is2);
//创建字符缓冲输出流对象,将合并内容写入合并流c,并输出合并的内容
BufferedOutputStream bos=new BufferedOutputStream(
new FileOutputStream("e:\\西部开源\\作业\\课后练习\\博客\\18\\合并流c.txt"));
//一次读取一个字节数组
byte[] bys=new byte[1024];
int len=0;
while((len=sis.read(bys))!=-1) {
bos.write(bys,0,len);
//刷新
bos.flush();
}
//关闭流,释放资源
bos.close();
sis.close();
}
```
**十、标准输入/输出流**
1、标准输入流:InputStream in = System.in;
2、标准输出流:PrintStream out = Syste.out;使用BufferedWriter 去包装System.out。功能:public void println(String x)
3、键盘录入
(1)Scanner(JDK5以后用)
(2)BufferedReader包装字符转换输入流,包装System.in(流方式键盘录入,java的装饰者模式)
**十一、Serializable**
1、概述:Serializable标记接口,没有构造方法,没有字段,也没有方法。
2、常见异常
(1)java.io.InvalidClassException:该类的序列版本号与从流中读取的类描述符的版本号不匹配。
(2)java.io.NotSerializableException:当前类未实现序列化功能的异常。
3、解决需要多次序列化的问题:让当前实现类序列化功能的这个类产生一个固定ID,点击程序中的×××警告线,即可产生固定ID。
4、某些属性不想被序列化解决方法:transient 属性类型 属性
5、手动修改标记类的属性/成员变量时,会改变序列化版本ID。
**十二、序列化流/反序列化流**
1、序列化流ObjectOutputStream。
(1)序列化:将对象按照流的方式存储到文本文件中或者在网络中传输,对象→流数据。
(2)构造方法:public ObjectOutputStream(OutputStream out)
(3)写功能:public final void writeObject(Object obj)
2、反序列化流ObjectInputStream。
(1)反序列化:将文本文件中的流对象或者网络传输中的流对象还原成对象,流数据→对象。
(2)构造方法:public ObjectInputStream(InputStream in)
(2)读功能:public final Object readObject()
3、使用序列化/反序列化功能,自定义类需实现Serializable接口,并重写toString()方法。自定义类实现标记接口,意味着成标记类。
**十三、Properties**
1、概述:Properties,表示了一个持久的属性集(简称:属性集合类) extends HashtableMap集合。可保存在流中或从流中加载,属性列表中每个键及其对应值都是一个字符串。
2、无参构造:public Properties()
3、特有功能:
(1)public Object setProperty(String key, String value):给属性列表中添加键和值,并且强制都使用String。
(2)public SetstringPropertyNames():遍历
(3)public String getProperty(String key)用指定的键在此属性列表中搜索属性。
4、可保存在流中或从流中加载,只能使用属性集合类:
(1)public void store(Writer writer,String comments):把集合中的数据保存文本文件中(属性集合)。
(2)public void load(Reader reader):将文本文件中的数据加载到属性集合中。
**十四、多线程**
1、基本概念
(1)单线程:程序的执行路径只有一条。
(2)多线程:程序的执行路径有多条。线程之间在抢占CPU的执行权(抢占资源),多线程的执行具有随机性。
(3)进程:系统间进行独立调配并且不可分割的独立单元。线程依赖于进程存在。
(4)线程:进程的一个独立单元。一个进程中有多个任务,把每个任务看成一个线程。
(5)synchronized:同步(同步锁)。
2、Thread类(Java提供)
(1)实现多线程程序的步骤:
方式一:
A、将类声明为 Thread 的子类;
B、该子类应重写 Thread 类的 run 方法;
C、在主线程进行该自定义的线程类的对象的创建。
方式二:
A、自定义一个类,实现Runnable接口;
B、实现接口中的run方法,对耗时的代码进行操作;
C、然后在主线程中创建该了对象,将该类对象做为一个资源类,创建Threadd类的对象,将刚才的资源类作为参数进行传递。
(2)常用方法:
A、public final void setName(String name):给线程命名。
B、public final String getName():获取线程名称。
C、public static Thread currentThread():返回当前正在执行的线程对象的引用。
(3)线程优先级相关方法:
A、public final int getPriority():返回线程的优先级。
B、public final void setPriority(int newPriority):更改线程的优先级。
C、线程默认优先级
A、public static final int MAX_PRIORITY 10 最大优先级
B、public static final int MIN_PRIORITY 1 最小优先级
C、public static final int NORM_PRIORITY 5 默认优先级
(4)其他方法:
A、public final void setDaemon(boolean on):参数为true时,表示为守护线程。将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。(守护线程不会立即结束,它会执行一段时间在结束),
该方法必须在启动线程前调用。
B、public final void join():等待该线程终止。interruputedException 中断异常。
C、public static void sleep(long millis)线程睡眠,指定是时间毫秒值。
D、public final void stop():强迫线程停止执行,不会再执行了。(该方法已过时,但仍然可以使用)。
E、public static void yield():暂停当前正在执行的线程对象,并执行其他线程。
3、相关面试题
(1)JVM是多线程程序吗?至少有几条线程?
解:JVM,Java虚拟机,识别main(主线程)。jvm是多线程的,至少有2条线程。
(2)如何实现多线程程序?
解:A、方法一:要实现多线程程序,需要开启进程,开启进程,需要创建系统资源,但是Java语言不能创建系统资源,只有C/C++可以创建系统资源, 利用c语言创建好的系统资源实现。
B、方法二:a、自定义一个类,实现Runnable接口;b、实现接口中的run方法,对耗时的代码进行操作;c、然后在主线程中创建该了对象,将该类对象做为一个资源类,创建Threadd类的对象,将刚才的资源类作为参数进行传递。
(3)stop()与interrupt()区别:
stop():强迫线程停止执行,程序不会再执行了(此方法已过时,但仍可使用)。
interrupt():中断线程,表示中断线程的一种状态。
(4)wait()与sleep()区别:
wait():wait()调用时,立即释放锁 (同步锁/Lock锁)。
sleep():线程睡眠,调用时不会释放锁。
1赞
收藏
评论