我的故事你说,我的文字我落,我值几两你定,我去何方我挑。
四大抽象基类 |
---|
InputStream |
OutputStream |
Reader |
Writer |
InputStream、OutputStream:
所有格式的数据
Reader、Writer:
因为涉及到字符编码的转换,因此只能处理纯文本类型的数据。
ObjectInputStream
ObjectOutputStream
序列化和反序列化
两个让Java类具备序列化和反序列化能力的接口
Serializable:static、transient
Externalizable:两个重写方法自己指定哪些需要序列化
主要就是指定Java中哪些属性值可以被序列化,哪些不能被序列化
任何一个可以被序列化的类都具备一个序列化版本ID
注解是给Java程序进行解释说明或者是在Java的编译期间、运行期间提供一些特殊的“服务”
注解的声明
@元注解 访问控制修饰符 @interface 注解名{ 属性类型 属性名() default 默认值; }
元注解–四个
注解名称 |
---|
@Target |
@Retention |
@Documented |
@Inherited |
帮助我们基于注解快速生成一个JavaBean类,借助几个SOURCE声明周期的注解,在Java编译时期将JavaBean有关的内容给我们生成到.class文件当中
注解名称 | 包含注解 |
---|---|
@Data | @ToString @Getter @Setter @EqualsAndHashCode |
@NoArgsConstructor | |
@AllArgsConstructor | |
@Builder |
反射是在Java运行期间,可以获取类中任何一块组成,以及可以调用或者运行类中任何一块内容
Class类是Java中所有类的类。Java中所有的类。都是Class类的一个实例对象
在Java当中,任何一个类一旦加载到JVM内存当中,那么我们就会把这个类创建称为Class类的一个实例对象,然后使用这个类的时候,JVM会通过Class的实例对象去看在这个类当中有没有我们调用的属性和方法。
通过Class类就可以获取任何一个类当中声明的任何一种成分,同时还可以调用这些成
反射第一步:获取该类的运行时类对象–获取该类的Class实例对象
任何一个类的Class实例对象,我们自己是无法创建的,他们都是在JVM内存加载的时候,由JVM内存自动创建的,在内存中仅且只有一份。因此我们只能获取,不能创建
同一个Class实例
代码示例:
ArrayList<String> list = new ArrayList<>();
//1、通过某个类的对象名.getClass()方法可以获取该类的class实列对象
Class < ? extends ArrayList > class1 = list.getClass();
//2、通过类名.class去获取该类的运行时类
Class<ArrayList> class2 = ArrayList. class;
//3、通过Class.forName(全限定类名)
Class<?> class3 = Class.forName("java.util.ArrayList");
System.out.println(class1==class2);//true
System.out.println(class2==class3);//true
反射的作用一:通过Class类获取类中的任何一个成分
代码示例
Class<Student> cls = Student.class;
Field field = cls.getField("phone");
System.out.println(field.getModifiers());//1
System.out.println(field.getName());//phone
System.out.println(field.getType());//class java.lang.String
Field[] fields = cls.getFields();
Field field2 = cls.getDeclaredField("name");
System.out.println(field2);//private java.lang.String com.sxuek.study.Student.name
Field[] declaredFields = cls.getDeclaredFields();
for(Field f : declaredFields) {
System.out.println(f);
//private java.lang.String com.sxuek.study.Student.name
//protected java.lang.Integer com.sxuek.study.Student.age
//java.lang.String com.sxuek.study.Student.sex
//public java.lang.String com.sxuek.study.Student.phone
}
Class<Student> cls = Student.class;
Method[] methods = cls.getDeclaredMethods();
for(Method method:methods) {
System.out.println(method.getModifiers());//2
System.out.println(method.getName());//run
System.out.println(method.getReturnType());//void
Parameter[] parameters = method.getParameters();
for(Parameter p : parameters) {
System.out.println(p.getType());//4 int 0 void class java.lang.String 1 int int int
System.out.println(p.getName());//sum call arg0 diff arg0 arg1
}
}
Constructor<Student> constructor = cls.getConstructor(String.class,Integer.class);
反射的作用二:通过反射调用类中的成分
代码示例:
Class<Student> clz = Student.class;
Constructor<Student> constructor = clz.getDeclaredConstructor(String.class,Integer.class);
constructor.setAccessible(true);
/**
* 可以根据获取的构造器创建这个类的对象
*/
Student student = constructor.newInstance("zs",20);
System.out.println(student);//Student [name=zs, age=20, sex=null, phone=null]
Field field = clz.getDeclaredField("name");
field.setAccessible(true);
Object object = field.get(student);
System.out.println(object);//zs
field.set(student,"ls");
System.out.println(student.getName());//ls
Method method = clz.getDeclaredMethod("diff",int.class,int.class);
method.setAccessible(true);
Object value = method.invoke(student, 2,1);
System.out.println(value);//1
package com.sxuek.study.reflectdemo;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class ObjectGen {
public static void main(String[] args) {
Teacher teacher = genObject(Teacher.class);
System.out.println(teacher);//null
Book book = genObject(Book.class);
System.out.println(book);//Book(bookName=流浪地球, author=刘慈欣, publisher=淘票票, price=39)
}
public static <T> T genObject(Class<T> cls) {
//1、获取这个类上声明的注解值--
MyAnno annotation = cls.getDeclaredAnnotation(MyAnno.class);
//文件的路径
String value = annotation.value();
//2、根据IO流读取文件数据获取配置项的值
Map<String, Object> map = new HashMap<>();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(value));
String line = null;
while((line = br.readLine()) != null) {
String[] array = line.split("=");
map.put(array[0], array[1]);
}
//3、根据反射获取类中构造器,构建对象
// T newInstance = cls.newInstance();//调用的是无参构造器 无参构造器必须存在,而且必须是public
Constructor<T> constructor = cls.getDeclaredConstructor();
constructor.setAccessible(true);
T t = constructor.newInstance();
//4、根据反射去获取类中的属性,然后结合构建的对象以及读取的文件中的数据给对应的属性赋值
Field[] fields = cls.getDeclaredFields();
for(Field f : fields) {
//5、属性赋值时 读取属性上的注解值,然后根据属性的注解值去配置文件获取对应的值给属性赋值
MyAnno anno = f.getDeclaredAnnotation(MyAnno.class);
String value2 = anno.value();
f.setAccessible(true);
f.set(t, map.get(value2));
}
return t;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(br != null) {
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
}