序列化
序列化:這種應用發生在要對一個對象做永久性保存的時候,可以把它保存到電腦磁盤,也可以保存到數據庫。而在你需要用到這個的時候可以從磁盤或數據庫中拿出來。eg:
序列化的對象必須實現java.io.Serializable接口。
package test;
import java.io.Serializable;
public class Person implements Serializable {
/**
* UID 用ID固定這個對象 防止被篡改
*/
private static final long serialVersionUID = 1567747183838728854L;
public Person(){}
public Person(String name, int age) {
System.out.println("test");
this.name = name;
this.age = age;
}
- public String testReflect; //後面反射內容時 測試用!
- private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
序列化:
package test;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class WritePerson {
public static void main(String[] args) throws FileNotFoundException, IOException {
String path = "src/myPerson.bin";
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path));
Person p = new Person("Floyd", 18);
out.writeObject(p);
System.out.println("序列化對象成功!");
out.close(); //可以把文件傳輸流也順帶關閉
}
}
反序列化:
package test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ReadPerson {
public static void main(String[] args) throws FileNotFoundException, IOException {
String path = "src/myPerson.bin";
ObjectInputStream in = new ObjectInputStream(new FileInputStream(path));
try {
Person p = (Person) in.readObject();
if(p != null)
System.out.println(p);
else
System.out.println("反序列化對象失敗!");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (in != null) {
in.close();
}
}
}
}
*實現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:
獲取類的方法:
package test;
public class reflectClass {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//1.通過類來得到Class對象
Class<?> clz1 = Person.class;
//2.通過對象來獲取其Class信息
Person p = new Person();
Class<?> clz2 = p.getClass();
//3.通過Class.forName()方式獲取Class信息
Class<?> clz3 = Class.forName("test.Person");
//使用newInstance()方法時Person類中必須要有一個無參的構造方法,否則會報錯
Person person = (Person) clz3.newInstance();
System.out.println(person);
}
}
Field 類(java.lang.reflact.field):
package test;
import java.lang.reflect.Field;
public class reflectField {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Person person = new Person();
person.setReflectTest("test");
person.setName("Tom");
person.setAge(18);
Class<?> clz = person.getClass();
//演示獲取公有字段
Field f = clz.getField("reflectTest");
System.out.println(f);
Object obj = f.get(person);
System.out.println(obj);
//演示獲取私有字段
Field f2 = clz.getDeclaredField("name");
f2.setAccessible(true);
System.out.println(f2);
Object obj2 = f2.get(person);
System.out.println(obj2);
f2.set(person, "James");
System.out.println(f2.get(person));
//用數組ForEach遍歷獲取所有字段
Field[] fs = clz.getDeclaredFields();
for (Field field : fs) {
System.out.println(field);
}
}
}
Constructor類:
使用方法與Field異曲同工。
如果是有參的構造方法,構造時需要如下操作(eg:T(int i, String s){this i= i;this s = s;})
Class<T> xxxClz = T.class;
Constructor<T> c = (Constructor<T>)xxxClz.getDeclaredConstructor(int.Class, String.Class);
c.setAccessible(true);
Object obj = c.newInstance(1,"a");
System.out.println(obj);
java.lang.reflect.method 類:
可以獲得返回值。