Java序列化,反射,注解(一)

序列化:
什么是序列化,为什么要做序列化,考虑一种场景,考虑这种应用发生在要对一个对象做永久性保存的时候, 可以把它保存到电脑磁盘,也可以保存到数据库。而在你需要用到这个对象的时候可以从磁盘或数据库拿出来。 比如有这么一个类定义class People { String name , int age } , 我现在 People one = new People(), one.name=“张三”, one.age= 24. 现在有了one这么一个对象,里面包含了张三的信息,我现在就可以把 one永久存储到数据库了,当我某一天想起张三时,就可以把one从数据库读出来。 我们就拿到了 one 这个对象, 又可以做进一步操作了。 (注意: 序列化只需要保存类的状态,也就是类中的成员变量,临时变量和方法对于序列化是 没任何意义的)


Demo1
Person.java:

package com.mq.class1;

import java.io.Serializable;

public class Person implements Serializable {

	private static final long serialVersionUID = 5209339615516670L;
	private String name;
	private int age;

	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = 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;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

}

将Person对象序列化到一个文件中:

package com.mq.class1;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/**
 * 将Person对象序列化到一个文件中
 * 
 * @author Administrator
 * 
 */
public class WritePerson {

	public static void main(String[] args) {
		String path = "src/person.bin";
		FileOutputStream fileOutputStream = null;
		ObjectOutputStream oStream = null;

		try {
			fileOutputStream = new FileOutputStream(path);
			oStream = new ObjectOutputStream(fileOutputStream);
			Person person = new Person("zhangsan", 18);
			oStream.writeObject(person);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (oStream != null) {
				try {
					oStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (fileOutputStream != null) {
				try {
					fileOutputStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	}
}

读取序列化后的文件:

package com.mq.class1;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * 读取序列化后的文件
 * 
 * @author Administrator
 * 
 */
public class ReadPerson {

	public static void main(String[] args) {
		String path = "src/person.bin";
		FileInputStream fileInputStream = null;
		ObjectInputStream inputStream = null;
		try {
			fileInputStream = new FileInputStream(path);
			inputStream = new ObjectInputStream(fileInputStream);
			Person person = (Person) inputStream.readObject();
			if (person != null) {
				System.out.println(person);
			} else {
				System.out.println("序列化失败");
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (inputStream != null) {
					inputStream.close();
				}
				if (fileInputStream != null) {
					fileInputStream.close();
				}

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}
}


可以将bean对象转化成xml文件,但必须需要这几个jar包:
http://download.csdn.net/detail/chaogu94/9618822
Demo2:
Person.java同上一个一样。
将可以序列化的对象转换成xml文件:

package com.mq.class1.seriazabletoxml;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.XStream;

/**
 * 将可以序列化的对象转换成xml文件
 * @author Administrator
 *
 */
public class WritePersonToXML {

	public static void main(String[] args) {
		String path = "src/person.xml";
		FileOutputStream fileOutputStream = null;
		List<Person> persons = new ArrayList<Person>();
		try {
			fileOutputStream = new FileOutputStream(path);
			for (int i = 0; i < 3; i++) {
				Person person = new Person("zhangsan" + i + 1, i + 1);
				persons.add(person);
			}
			//创建一个XStream对象,只需要调用toXML方法就可以将可以序列化的对象转换成xml文件
			XStream xStream = new XStream();
			xStream.toXML(persons, fileOutputStream);

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (fileOutputStream != null) {
				try {
					fileOutputStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	}
}

读取被序列化之后生成的xml文件:

package com.mq.class1.seriazabletoxml;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.XStream;

/**
 * 读取被序列化之后生成的xml文件
 * 
 * @author Administrator
 * 
 */
public class ReadPersonFromXML {

	public static void main(String[] args) {
		String path = "src/person.xml";
		List<Person> persons = null;
		FileInputStream inputStream = null;
		try {
			inputStream = new FileInputStream(path);
			XStream xStream = new XStream();
			persons = (ArrayList<Person>) xStream.fromXML(inputStream);
			System.out.println(persons);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (inputStream != null)
				try {
					inputStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}

	}
}


反射:
概念:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

Person类:

package com.mq.class1.reflect;

/**
 * 这里包含了公共字段、私有字段、静态属性、构造方法等,一般类中包含的特性都有,用来作为练习最合适
 * @author Administrator
 *
 */
public class Person {
	public static String TAG = "Person";
	public static String getTAG(){
		return TAG;
	}
	public int id = 10;
	private String name;
	private int age;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	private void setAge(int age) {
		this.age = age;
	}

	public Person() {
		super();
		// this.id=10;
		// TODO Auto-generated constructor stub
	}

	public Person(int id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
	}

	public int sum(int... numbers) {
		int total = 0;
		for (int n : numbers)
			total += n;
		return total;
	}

}

创建Class:

package com.mq.class1.reflect;

public class ReflectTest {

	public static void main(String[] args) throws ClassNotFoundException,
			InstantiationException, IllegalAccessException {
		/*
		 * 创建Class的三种方法
		 */
		// 1.通过类来创建
		Class<?> class1 = Person.class;
		// 2.通过对象来创建
		Person person = new Person();
		Class<?> class2 = person.getClass();
		// 3.通过forName方法来创建
		Class<?> class3 = Class.forName("com.mq.class1.reflect.Person");
		// 证明三个方法创建出来的class是一样的,结果都是true
		System.out.println(class1 == class2);
		System.out.println(class2 == class3);

		/*
		 * 创建实例
		 */
		Person person2 = (Person) class1.newInstance();
		System.out.println(person2);
	}
}

对Field的操作:

package com.mq.class1.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class FieldTest {

	public static void main(String[] args) throws SecurityException,
			NoSuchFieldException, IllegalArgumentException,
			IllegalAccessException {
		/*
		 * 获取公共的属性的Field和值
		 */
		Class<?> class1 = Person.class;
		Person person = new Person(101, "zhangsan", 18);
		Field field = class1.getField("id");
		// 获取字段名为id的引用
		System.out.println(field);
		Object object = field.get(person);
		System.out.println(object);

		/*
		 * 获取私有的属性的Field和值
		 */
		field = class1.getDeclaredField("age");
		System.out.println(field);
		// 获取属性值的时候要将此参数设置为true
		field.setAccessible(true);
		object = field.get(person);
		System.out.println(object);
		// 更改person的age属性
		field.set(person, 100);
		System.out.println(person.getAge());

		/*
		 * 获取所有的属性
		 */
		Field[] fields = class1.getDeclaredFields();
		for (Field field2 : fields) {
			System.out.println(field2);
		}

		/*
		 * 获取静态属性
		 */
		field = class1.getDeclaredField("TAG");
		System.out.println("该属性是否为静态属性:"
				+ Modifier.isStatic(field.getModifiers()));
		// 获取属性值
		field.setAccessible(true);
		object = field.get(null);// 静态属性是属于类的,所以是null
		System.out.println(object);
		field.set(null, "new value");
		System.out.println(Person.getTAG());
	}
}

Construct:
新创建一个雇员类Employee.java

package com.mq.class1.reflect;

public class Employee {

	private static Employee employee;//使用单例模式创建雇员对象
	private int id;
	private String name;

	private Employee() {

	}

	private Employee(int id, String name) {
		this.id = id;
		this.name = name;
	}

	public static Employee getInstance() {
		if (employee == null)
			employee = new Employee();
		return employee;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", name=" + name + "]";
	}

}

ConstructTest:

package com.mq.class1.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ConstructTest {

	public static void main(String[] args) throws InstantiationException,
			IllegalAccessException, SecurityException, NoSuchMethodException,
			IllegalArgumentException, InvocationTargetException {
		// 使用无参/默认构造器创建对象实例
		Class<?> class1 = Person.class;
		Person person = (Person) class1.newInstance();
		System.out.println(person);

		// 调用公开构造器创建对象实例(有参)
		Constructor<Person> constructor = (Constructor<Person>) class1
				.getConstructor(int.class, String.class, int.class);
		person = constructor.newInstance(12, "zhangsan", 20);
		System.out.println(person);

		// 对Employee类的无参构造方法进行反射
		Class<Employee> empClass = Employee.class;
		Constructor<Employee> empConstructor = empClass
				.getDeclaredConstructor();
		empConstructor.setAccessible(true);
		Employee employee = empConstructor.newInstance();
		System.out.println(employee);

		// 对Employee类的无参构造方法进行反射
		empClass = Employee.class;
		empConstructor = empClass
				.getDeclaredConstructor(int.class,String.class);
		empConstructor.setAccessible(true);
		employee = empConstructor.newInstance(101,"zhang");
		System.out.println(employee);
	}
}

Method:

package com.mq.class1.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 对方法的反射
 * 
 * @author Administrator
 * 
 */
public class MethodTest {

	public static void main(String[] args) throws SecurityException,
			NoSuchMethodException, IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		/*
		 * 操作get方法
		 * 对无参数有返回值的方法进行反射
		 */
		Person person = new Person(101, "zhangsan", 20);
		Class<Person> class1 = Person.class;
		Method method = class1.getDeclaredMethod("getAge");// 有最少一个参数,第一个方法名,第二个之后都是参数类型
		int age = (Integer) method.invoke(person);
		System.out.println(age);// 结果为20

		/*
		 * 操作set方法
		 * 对有参数无返回值方法进行反射
		 */
		method = class1.getDeclaredMethod("setAge", int.class);
		method.setAccessible(true);
		method.invoke(person, 30);
		System.out.println(person.getAge());// 结果为30

		/*
		 * 指定数组参数范例
		 * 对参数为数组的方法进行反射
		 */
		method = class1.getDeclaredMethod("sum", int[].class);
		age = (Integer) method.invoke(person, new int[] { 1, 2, 3 });
		System.out.println(age);// 结果为6
	}

}

根据反射写一个小案例,要求:提供一个方法可以反射出一个类中所有的字段和值

package com.mq.class1.reflect;

import java.lang.reflect.Field;

public class MethodDemo {

	public static void main(String[] args) throws IllegalArgumentException,
			IllegalAccessException {

		Person person = new Person(101, "zhangsan", 20);
		String string = toString(person);
		System.out.println(string);
	}

	public static String toString(Object obj) throws IllegalArgumentException,
			IllegalAccessException {
		StringBuilder builder = new StringBuilder();
		Class<?> class1 = obj.getClass();
		Field[] fields = class1.getDeclaredFields();

		for (Field field : fields) {
			field.setAccessible(true);
			builder.append(field.getName());
			builder.append("=");
			builder.append(field.get(obj));
			builder.append(", ");
		}
		if (builder.length() > 0) {
			builder.delete(builder.length() - 2, builder.length());
		}
		return class1.getSimpleName() + "[" + builder + "]";
	}

}

未完待续。。。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值