javacore 序列化&反射

来源:互联网 发布:监守自盗观后感知乎 编辑:程序博客网 时间:2024/05/17 03:22

序列化

序列化:这种应用发生在要对一个对象做永久性保存的时候,可以把它保存到电脑磁盘,也可以保存到数据库。而在你需要用到这个的时候可以从磁盘或数据库中拿出来。
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 类:
可以获得返回值。



1 0