1.如何用file操作目录和文件?
java对待目录和文件统一使用file来表示,在创建file对象时,使用isDictionary和isFile方法进行判断
1 package test;
2
3 import java.io.File;
4
5 import java.io.IOException;
6
7 public class FileTest {
8
9 public static void main(String[] args) {
10
11 // TODO Auto-generated method stub
12
13 File file1 = new File("E:/a.txt");
14
15 if (!file1.exists()) {
16
17 try {
18
19 file1.createNewFile();
20
21 } catch (IOException e) {
22
23 // TODO Auto-generated catch block
24
25 e.printStackTrace();
26
27 System.out.println("创建文件失败!");
28
29 }
30
31 }
32
33 // 创建一个目录
34
35 File dir = new File("E:/testxjq");
36
37 // 判断是否为目录
38
39 if (dir.isDirectory()) {
40
41 // 得到所有的文件
42
43 String[] files = dir.list();
44
45 for (String fileName : files) {
46
47 // 用目录和文件名生成File对象
48
49 File f = new File(dir.getPath() + File.separator + fileName);
50
51 // 对生成的File对象进行分类打印
52
53 if (f.isFile()) {
54
55 System.out.println("文件为:" + f.getName());
56
57 } else if (f.isDirectory()) {
58
59 System.out.println("目录为:" + f.getName());
60
61 }else{
62
63 System.out.println("null");
64
65 }
66
67 }
68
69 }
70
71 else{
72
73 System.out.println("dsddssf");
74
75 }
76
77 }
78
79 }
总结:FIle类的常用方法:
(1)构造方法:传递字符串形式的文件路径的方式来创建file对象,file并不会检查该目录或者文件是否已经存在。
(2)IsDirectory和isFile方法用于判断File对象所代表的是目录还是普通的文件。
(3)createNewFile方法,采用file对象所存储的路径和文件名进行创建。
(4)List方法,用于目录,得到目录下所有的文件名,类型为字符串数组
(5)getName():得到文件名,不包含他的路径。
(6)Delete,删除文件
2.写一个复制文件的程序?
1 package test;
2
3 import java.io.FileInputStream;
4
5 import java.io.FileOutputStream;
6
7 import java.io.IOException;
8
9 public class FileCopy {
10
11
12
13 public static void main(String[] args) throws IOException {
14
15 // TODO Auto-generated method stub
16
17 //生成的输入文件的输入流对象
18
19 FileInputStream fin = new FileInputStream("e:/a.txt");
20
21 //生成输出文件的输出流对象
22
23 FileOutputStream fout = new FileOutputStream("e:/b.txt");
24
25 //定义一个暂存数据的数组
26
27 byte[] buff = new byte[256];
28
29 //每次读取数据的长度
30
31 int len = 0;
32
33 while((len=fin.read(buff))>0){
34
35 fout.write(buff, 0, len);
36
37 }
38
39 fin.close();
40
41 fout.close();
42
43 }
44
45
46
47 }
3.如何使用随机存取文件RandomAccessfile类?
1 package test;
2
3 import java.io.IOException;
4
5 import java.io.RandomAccessFile;
6
7 public class RanAccessFile {
8
9
10
11 public static void main(String[] args) throws IOException {
12
13 // TODO Auto-generated method stub
14
15 //创建随机读取文件对象
16
17 RandomAccessFile file = new RandomAccessFile("E:/a.txt","rw");
18
19 //遍历file字节数据
20
21 for(int i = 0;i<file.length();i++){
22
23 //从内存中读取的都为二进制,将二进制转换为字节,字节转为字符
24
25 byte b = (byte)file.read();
26
27 char c = (char)b;
28
29 //如果对应的字符为a
30
31 if(c=='a'){
32
33 //指针回退原位置
34
35 file.seek(i);
36
37 //重写该位置的数据
38
39 file.write('c');
40
41 }
42
43 }
44
45 file.close();
46
47 System.out.println("ok");
48
49 }
50
51 }
总结:length方法获取文件的内容长度
seek方法随机达到任何需要存取数据的地方
read方法获取当前位置的数据,write方法写入数据
close方法关闭文件的打开。
4.字节流的处理方式?
计算机内部处理数据总是以一个byte为基本单位,字节流 就是每次读取的单位为byte,字节流是所有的流的基础,也是其他高级流 的前提。
java中的基础字节输入流和输出流类别:
i
nputStream和outputStream
以及:
FileInputStream和FileOutputStream
ObjectInputStream 和ObjectOutputStream
BufferedInputStream和BufferedOutputStream
也主要通过read和write方法把byte数组中的数据写入和读出。
5.字符流的处理方式?
字符流是由字节流包装而来的,输入和输出流的格式为
StringReader 和StringWriter
BufferedReader 和BufferedWriter:有特殊具备的ReadLine()方法
一个例子:
1 package test;
2
3 import java.io.BufferedReader;
4
5 import java.io.FileInputStream;
6
7 import java.io.IOException;
8
9 import java.io.InputStream;
10
11 import java.io.InputStreamReader;
12
13 /*
14
15 * 按行读取文件并且打印
16
17 * */
18
19 public class ReaderTest {
20
21 public static void main(String[] args) throws IOException {
22
23 // TODO Auto-generated method stub
24
25 //根据文件得到一个输入流
26
27 InputStream in = new FileInputStream("E:/a.txt");
28
29 //得到inputStreamReader对象
30
31 InputStreamReader isr = new InputStreamReader(in,"GBK");
32
33 //根据输入流创建Reader对象
34
35 BufferedReader br = new BufferedReader(isr);
36
37 //创建StringBuffer对象临时保存字符内容
38
39 StringBuffer sb = new StringBuffer();
40
41 String str = null;
42
43
44
45 while((str = br.readLine())!=null){
46
47 sb.append(str);
48
49 }
50
51 System.out.println("content:"+sb);
52
53 br.close();
54
55 isr.close();
56
57 in.close();
58
59 }
60
61 }
6.什么是序列化?
java对象内村中的数据采编成一串二进制数据,把这些数据存放在可以持久的数据存储设备,当需要还原数据时,通过反序列化,把对象重新还原到内存中。
java.io.Serializable接口是进行序列化的类的标志性接口,本省没有任何需要实现的抽象的方法,告诉jvm该类的对象可以进行序列化,序列化id由serialVersionUID变量提供。
serialVersionUID用来辨别类,如果在在反序列的时候,两个类的类名是相同的,就通过该id来进行辨别。
一个实现序列化和反序列化的例子:
1 package test;
2
3 import java.io.FileInputStream;
4
5 import java.io.FileNotFoundException;
6
7 import java.io.FileOutputStream;
8
9 import java.io.IOException;
10
11 import java.io.ObjectInputStream;
12
13 import java.io.ObjectOutputStream;
14
15 import java.io.Serializable;
16
17
18
19 class Person implements Serializable{
20
21 public String getName() {
22
23 return name;
24
25 }
26
27 public void setName(String name) {
28
29 this.name = name;
30
31 }
32
33 public int getAge() {
34
35 return age;
36
37 }
38
39 public void setAge(int age) {
40
41 this.age = age;
42
43 }
44
45 //序列化id
46
47 private static final long serialVersionUID = 1L;
48
49 private String name;
50
51 private int age;
52
53 }
54
55 public class SerialTest {
56
57 public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
58
59 // TODO Auto-generated method stub
60
61 Person stu = new Person();
62
63
64
65 stu.setAge(20);
66
67 stu.setName("admin");
68
69 //创建对象的输出流,将对象输出到磁盘
70
71 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("e:/a.dat"));
72
73 //开始写对象
74
75 oos.writeObject(stu);
76
77 oos.close();
78
79 //创建对象的输入流
80
81 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("e:/a.dat"));
82
83 //从磁盘中读取对象,再转换成一个实体
84
85 Person p = (Person)ois.readObject();
86
87 //输出
88
89 System.out.println(p.getAge());
90
91 System.out.println(p.getName());
92
93 }
94
95 }
96
97 结果:
98
99 20
100
101 admin
7.什么是多线程?
进程是整个程序或者部分程序的动态执行,线程是一组指令的集合,可以在程序中单独的运行。多线程是这样的一种机制,允许在程序中并发执行多个指令流,每个指令流都被称为一个线程,彼此间相互独立。
好处:
<1>使用线程可以把占据长时间的程序中的任务放到后台去处理。
<2>加快程序的运行速度
<3>在等待的任务下,线程可以去释放一些资源,如占用的内存。
8.进程和线程的区别?
<1>线程的划分尺度小于进程,线程属于某个进程
<2>进程是程序的一种动态形式,是CPU,内存等资源占用的基本单位,线程不可以独立拥有这些资源。
<3>线程之间共享一块内存区域,通信比较方便。
<4>进程在执行的过程中,会包含比较固定的入口,执行的顺序和出口,线程的这些过程会被应用程序所控制。
9.如何让一个类成为线程类?
方法一:实现java.lang.Runable接口
方法二:继承自java.lang.Thread类
本质上,Thread以及实现了Runable接口,你在继承Thread类的时候,已经实现了Runable接口,只是Thread类还提供了额外的方法。
1 package test;
2
3 public class RunTest implements Runnable {
4
5 @Override
6
7 public void run() {
8
9 // TODO Auto-generated method stub
10
11 System.out.println("thread running");
12
13 }
14
15 }
16
17
18
19 package test;
20
21 public class RunTest extends Thread {
22
23 @Override
24
25 public void run() {
26
27 // TODO Auto-generated method stub
28
29 System.out.println("thread running");
30
31 }
32
33 }
10.Runnable接口和Thread类的区别?
<1>如果线程类继承了Thread类那么久不可以再继承其他的类,而Runnable接口是可以的,因为Java支持单继承。
<2>如果要使用很多的线程的方法,使用Thread更方便。
<3>实现Runnable接口的线程类的多个线程,可以更方便地访问同一个变量。
11.如何去启动一个线程?
针对继承自Thread类和实现了Runnable接口:
1 package test;
2
3 class ThreadTest extends Thread{
4
5 public void run(){
6
7 System.out.println("实现了Thread类");
8
9 }
10
11 }
12
13 class RunnableTest implements Runnable{
14
15 public void run(){
16
17 System.out.println("实现了runnable接口");
18
19 }
20
21 }
22
23
24
25 public class ThreadStartTest {
26
27 public static void main(String[] args) {
28
29 //直接继承了Thread ,创建一个Thread的实例
30
31 ThreadTest t1 = new ThreadTest();
32
33 //t1启动
34
35 t1.start();
36
37 //如果是实现了接口的线程类,需要用对象的实例作为Thread类构造方法的参数
38
39 Thread t2 = new Thread(new RunnableTest());
40
41 t2.start();
42
43 }
44
45 }
12.如何使用sychronized使得线程同步?
工作原理:每个对象都有一个线程锁,sychronized可以使用任何一个对象的线程锁来锁住一段代码,任何想要进入该段代码的线程必须在解锁后才可以继续进行,否则就进入等待状态。其中就进入等待的状态。
1 package test;
2
3 class Test extends Thread{
4
5 public static int index;
6
7 //定义一个对象用于控制线程同步
8
9 public static Object obj = new Object();
10
11 public void run(){
12
13 synchronized (obj) {
14
15 for(int i =0;i<10;i++){
16
17 System.out.println(index++);
18
19 }
20
21 }//end of synchronized
22
23 }
24
25 }
26
27
28
29 public class MyThread {
30
31 public static void main(String[] args) {
32
33 // TODO Auto-generated method stub
34
35 new Test().start();
36
37 new Test().start();
38
39 new Test().start();
40
41 }
42
43 }
13.如何使用线程池?
组成部分:
完成一个任务的一个或者多个线程;
用于调度管理的管理线程;
要求执行的任务队列;
目的:为了最大程度的复用对象,最大程度的利用线程。
14.反射的理解?
反射提供了一种动态的功能,主要通过反射相关的API,就可以知道一个陌生的java类的所有的信息,包括属性、方法、构造器,这些元素完全可以在运行时动态的创建或者调用,不必再JVM运行时就进行确定。利用的是该类形成的java.lang.Class类的实例。
java用class类来代表所有的类,方便开发者掌控类的信息,如果得到了一个类的属性,方法等信息,就可以利用这个class创建实例,调用任何的方法,访问任何的属性,这就是反射的主要用处。
反射机制的API,主要集中在java.lang.reflect包下。
15.class类的的含义和作用是什么?
第一步:一个类会在什么时候被加载到JVM中呢?
<1>通过new关键字,使用该类的对象
Student stu = new Student()
<2>访问该类的静态的成员
Student.age;
<3>使用class.forName()方法进行加载
class.forName(“com.test.Student”);
第二布:如何得到一个类的class对象?
<1>Class.forName()方法
<2>访问类的class属性
<3>创建对象,调用对象的getClass()方法。
16.如何操作类的成员变量?field
反射式可以获取到类的对象,那就可以通过对象去获取成员变量。
方法:getDeclareField()方法或者getDeclareFields()方法获取。
一个例子:
1 package test;
2
3 import java.lang.reflect.Field;
4
5 //测试类
6
7 class Teacher{
8
9 public Teacher(String name, int age) {
10
11 super();
12
13 this.name = name;
14
15 this.age = age;
16
17 }
18
19 //通过反射将会访问到的属性
20
21 String name;
22
23 int age;
24
25 }
26
27 public class FieldTest {
28
29 public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
30
31 Teacher t1 = new Teacher("admin",23);
32
33 Teacher t2 = new Teacher("王老师",52);
34
35 System.out.println(compare(t1,t2).name+"'s age is bigger!");
36
37 }
38
39 //利用反射机制定义一个通用的比较的方法
40
41 @SuppressWarnings("unused")
42
43 private static Teacher compare(Teacher tea1,Teacher tea2) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
44
45 //第一个策略:通过对象的getClass()方法得到类的class对象
46
47 Field field = tea1.getClass().getDeclaredField("age");
48
49 //第二个策略:通过类的class的静态属性得到类的class对象
50
51 field = Teacher.class.getDeclaredField("age");
52
53 //获得两个对象的age值
54
55 int val1 = (int) field.get(tea1);
56
57 int val2 = (int) field.get(tea2);
58
59 //进行比较
60
61 if(val1>val2){
62
63 return tea1;
64
65 }else{
66
67 return tea2;
68
69 }
70
71 }//end of compare
72
73 }
17.如何通过反射操作类的方法?Method?
1 package test;
2
3 import java.lang.reflect.InvocationTargetException;
4
5 import java.lang.reflect.Method;
6
7
8
9 class MethodTestClass {
10
11 public void m1() {
12
13 System.out.println("m1 is called!");
14
15 }
16
17
18
19 public void m2() {
20
21 System.out.println("m2 is called");
22
23 }
24
25 }
26
27
28
29 public class CallMethodTest {
30
31
32
33 public static void main(String[] args)
34
35 throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
36
37 // TODO Auto-generated method stub
38
39 args = new String[] { "m1" };
40
41 // 得到方法名
42
43 String methodName = args[0];
44
45 if (methodName != null) {
46
47 // 得到class实例
48
49 Class<MethodTestClass> clazz = MethodTestClass.class;
50
51 // 通过该实例去得到方法
52
53 Method m = clazz.getDeclaredMethod(methodName);
54
55 // 通过方法,如果方法不为空,就创建对应类的实例
56
57 if (m != null) {
58
59 MethodTestClass obj = clazz.newInstance();
60
61 // 通过m调用唤醒的方法,去唤醒这个对象
62
63 m.invoke(obj);
64
65 }
66
67 }
68
69 }
70
71 }
72
73
74
75
18.如利用反射去实例化一个类?
两种情况:
<1>默认的无参数的额构造方法:
Class类的newInstance()方法
<2>对于有参数的构造方法:
先获取一个constructor实例,再用newInsatnce()方法创建对象。
一个例子:
1 package test;
3 import java.lang.reflect.Constructor;
5 import java.lang.reflect.InvocationTargetException;
9 class people{
11 public String getName() {
13 return name;
15 }
17 public void setName(String name) {
18
19 this.name = name;
20
21 }
22
23 public int getAge() {
25 return age;
27 }
28
29 public void setAge(int age) {
31 this.age = age;
33 }
34
35 @Override
36
37 public String toString() {
38
39 return "people [name=" + name + ", age=" + age + "]";
40
41 }
42
43 public people() {
45 super();
46
47 // TODO Auto-generated constructor stub
48
49 }
50
51 public people(String name, int age) {
52
53 super();
54
55 this.name = name;
56
57 this.age = age;
58
59 }
60
61 private String name;
62
63 private int age;
64
65 }
66
67
68
69 public class NewInstanceTest {
70
71
72
73 public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
74
75 // TODO Auto-generated method stub
76
77 //step1:获取Class对象
78
79 Class<people> clazz = people.class;
80
81 //step2:途径一:使用无参数的构造方法
82
83 //class对象直接获取实例
84
85 people obj = clazz.newInstance();
86
87 System.out.println("第一个对象:"+obj);
88
89
90
91
92
93 obj.setName("xsxs");
94
95 obj.setAge(50);
96
97 System.out.println("使用get/set方法后的名字:"+obj.getName());
98
99 System.out.println("使用get/set方法后的年龄:"+obj.getAge());
100
101
102
103
104
105 //step3:途径二:使用带参数的构造方法
106
107 //为构造器注入对应的值
108
109 Constructor<people> con = clazz.getConstructor(String.class,int.class);
110
111 obj = con.newInstance("admin",30);
112
113 System.out.println("第二个对象:"+obj);
114
115 }
116
117 }
19.如何利用反射来访问私有的成员?
1 package test;
2
3 import java.lang.reflect.Field;
4
5 class PrivateTestClass{
6
7 //定义构造方法
8
9 public PrivateTestClass(String field) {
10
11 super();
12
13 this.field = field;
14
15 }
16
17 private String field;//定义一个私有的属性
18
19 }
20
21 public class PrivateTest {
22
23 public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
24
25 // TODO Auto-generated method stub
26
27 //创建测试类的实例
28
29 PrivateTestClass ptc = new PrivateTestClass("hello");
30
31 //通过该实例得到Class对象
32
33 Class clazz = ptc.getClass();
34
35 //通过对象调用方法得到字段字段
36
37 Field myprivatefield = clazz.getDeclaredField("field");
38
39 //设置访问属性为true
40
41 myprivatefield.setAccessible(true);
42
43 //get方法返回该Field对象所代表的特定的值
44
45 System.out.println(myprivatefield.get(ptc));
46
47 }
48
49 }
20.如何通过反射来覆盖数据对象的toString()方法?
产生的背景:
如果在一个类中要改变属性名称,新增属性,去掉属性,则在toString方法中也会重新再加入或者删除某些属性。
1 package test;
2 import java.lang.reflect.Field;
3 class DataObject{
4 public String getName() {
5
6 return name;
7
8 }
9
10 public void setName(String name) {
11
12 this.name = name;
13
14 }
15
16 public int getAge() {
17
18 return age;
19
20 }
21
22 public void setAge(int age) {
23
24 this.age = age;
25
26 }
27
28 public DataObject() {
29
30 super();
31
32 // TODO Auto-generated constructor stub
33
34 }
35
36 public DataObject(String name, int age) {
37
38 super();
39
40 this.name = name;
41
42 this.age = age;
43
44 }
45
46 //为该类定义了俩个属性
47
48 private String name;
49
50 private int age;
51
52 //在类中实现自己的ToString方法
53
54 public String toString(){
55
56 //定义一个StringBuffer用于进行拼接
57
58 StringBuffer sb = new StringBuffer();
59
60 //通过反射得到所有成员变量的fields
61
62 Field[] fields = this.getClass().getDeclaredFields();
63
64 //遍历集合
65
66 for(Field f:fields){
67
68 //得到一个变量的名
69
70 sb.append(f.getName());
71
72 //拼接上==
73
74 sb.append("=");
75
76 //得到变量的值
77
78 try {
79
80 sb.append(f.get(this));
81
82 } catch (IllegalArgumentException e) {
83
84 // TODO Auto-generated catch block
85
86 e.printStackTrace();
87
88 } catch (IllegalAccessException e) {
89
90 // TODO Auto-generated catch block
91
92 e.printStackTrace();
93
94 }
95
96 //每次拼接完一个变量,换行处理/空格处理
97
98 sb.append(" ");
99
100 }
101
102 //返回拼接后的字符串
103
104 return sb.toString();
105
106 }//end of toString()
107
108 }
109
110 public class DataObjectTest {
111 public static void main(String[] args) throws InstantiationException, IllegalAccessException {
112
113 // TODO Auto-generated method stub
114
115 //利用动态代理去实例化一个类
116
117 DataObject obj = new DataObject();
118
119 @SuppressWarnings("unchecked")
120
121 Class<DataObject> clazz = (Class<DataObject>) obj.getClass();
122
123 DataObject my = clazz.newInstance();
124
125 //利用属性方法为属性赋值
126
127 my.setAge(100);
128
129 my.setName("dddddd");
130
131 //输出打印时,调用了自定义toString方法
132
133 System.out.println(my);
134
135 }
136 }