javacore 序列化&反射

序列化

序列化:這種應用發生在要對一個對象做永久性保存的時候,可以把它保存到電腦磁盤,也可以保存到數據庫。而在你需要用到這個的時候可以從磁盤或數據庫中拿出來。
eg:
序列化的對象必須實現java.io.Serializable接口。
  1. package test;
  2. import java.io.Serializable;
  3. public class Person implements Serializable {
  4. /**
  5. * UID 用ID固定這個對象 防止被篡改
  6. */
  7. private static final long serialVersionUID = 1567747183838728854L;
  8. public Person(){}
  9. public Person(String name, int age) {
  10. System.out.println("test");
  11. this.name = name;
  12. this.age = age;
  13. }
  14.    
  15.    public String testReflect;    //後面反射內容時 測試用!
  16. private String name;
  17. private int age;
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. public int getAge() {
  25. return age;
  26. }
  27. public void setAge(int age) {
  28. this.age = age;
  29. }
  30. }
序列化:
  1. package test;
  2. import java.io.FileNotFoundException;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.io.ObjectOutputStream;
  6. public class WritePerson {
  7. public static void main(String[] args) throws FileNotFoundException, IOException {
  8. String path = "src/myPerson.bin";
  9. ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path));
  10. Person p = new Person("Floyd", 18);
  11. out.writeObject(p);
  12. System.out.println("序列化對象成功!");
  13. out.close();    //可以把文件傳輸流也順帶關閉
  14. }
  15. }
反序列化:
  1. package test;
  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.io.IOException;
  5. import java.io.ObjectInputStream;
  6. public class ReadPerson {
  7. public static void main(String[] args) throws FileNotFoundException, IOException {
  8. String path = "src/myPerson.bin";
  9. ObjectInputStream in = new ObjectInputStream(new FileInputStream(path));
  10. try {
  11. Person p = (Person) in.readObject();
  12. if(p != null)
  13. System.out.println(p);
  14. else
  15. System.out.println("反序列化對象失敗!");
  16. } catch (ClassNotFoundException e) {
  17. // TODO Auto-generated catch block
  18. e.printStackTrace();
  19. } finally {
  20. if (in != null) {
  21. in.close();
  22. }
  23. }
  24. }
  25. }
*實現Externalizable接口可以控制對象的序列化與反序列化,可以在序列化時寫非自身的變量。或者只序列化部分對象,篡改對象。

反射

反射能做什麼?

1.運行反射機制可以分析類
2.運行反射機制可以分析、修改類
3.可以利用Method方法、操作對象
4.可以利用字符串動態生成

about Java.lang.reflect 包

Class(java.lang.Class<T>)
表示正在運行的Java應用程序中的類和接口
Field
代表類或接口的成員,及相關信息
Method
提供類或接口上單獨某個方法(以及訪問該方法)的信息
Constructor
提供關於類的單個構造方法的信息以及對他的訪問權限。
Array
提供了動態創建和訪問Java數組的方法。

Class類
^我們可以簡單地將Class看作是類(如:java.lang.String)的代碼本身(類的運行時信息)。
^Object類的getClass() 方法將返回對象對應的Class 類實例。
^Class 類的常用方法:
*static Class<?> forName(String className)
    返回與帶有給定字符串名的類或接口相關聯的Class對象。
*T newInstance()
    創建此Class 對象所表示的類的一個新實例。
^基本數據類型和關鍵字void 也表示爲Class 對象。
eg:
獲取類的方法:
  1. package test;
  2. public class reflectClass {
  3. public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
  4. //1.通過類來得到Class對象
  5. Class<?> clz1 = Person.class;
  6. //2.通過對象來獲取其Class信息
  7. Person p = new Person();
  8. Class<?> clz2 = p.getClass();
  9. //3.通過Class.forName()方式獲取Class信息
  10. Class<?> clz3 = Class.forName("test.Person");
  11. //使用newInstance()方法時Person類中必須要有一個無參的構造方法,否則會報錯
  12. Person person = (Person) clz3.newInstance();
  13. System.out.println(person);
  14. }
  15. }

Field 類(java.lang.reflact.field):
  1. package test;
  2. import java.lang.reflect.Field;
  3. public class reflectField {
  4. public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
  5. Person person = new Person();
  6. person.setReflectTest("test");
  7. person.setName("Tom");
  8. person.setAge(18);
  9. Class<?> clz = person.getClass();
  10. //演示獲取公有字段
  11. Field f = clz.getField("reflectTest");
  12. System.out.println(f);
  13. Object obj = f.get(person);
  14. System.out.println(obj);
  15. //演示獲取私有字段
  16. Field f2 = clz.getDeclaredField("name");
  17. f2.setAccessible(true);
  18. System.out.println(f2);
  19. Object obj2 = f2.get(person);
  20. System.out.println(obj2);
  21. f2.set(person, "James");
  22. System.out.println(f2.get(person));
  23. //用數組ForEach遍歷獲取所有字段
  24. Field[] fs = clz.getDeclaredFields();
  25. for (Field field : fs) {
  26. System.out.println(field);
  27. }
  28. }
  29. }

Constructor類:
使用方法與Field異曲同工。
如果是有參的構造方法,構造時需要如下操作(eg:T(int i, String s){this i= i;this s = s;})
  1. Class<T> xxxClz = T.class;
  2. Constructor<T> c = (Constructor<T>)xxxClz.getDeclaredConstructor(int.Class, String.Class);
  3. c.setAccessible(true);
  4. Object obj = c.newInstance(1,"a");
  5. System.out.println(obj);

java.lang.reflect.method 類:
可以獲得返回值。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章