1.如何用file操做目錄和文件?java
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對象所表明的是目錄仍是普通的文件。app
(3)createNewFile方法,採用file對象所存儲的路徑和文件名進行建立。dom
(4)List方法,用於目錄,獲得目錄下全部的文件名,類型爲字符串數組jvm
(5)getName():獲得文件名,不包含他的路徑。ide
(6)Delete,刪除文件測試
2.寫一個複製文件的程序?this
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中的基礎字節輸入流和輸出流類別:
inputStream和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 }