框架设计的灵魂
创建对象的时候
1. 案例
现在创建对象: Person per=new Person()
2.案例:
IO流中的问题: 创建文件名 a.txt a(1).txt
写程序的过程中,随时保存对象的信息(状态保存)
3.案例:
场景还原 前端做了小游戏 , 贪吃蛇 要求保存游戏进度 保存对象所有的信息
加载对象信息:
加载已经保存的信息的
保存形式:
IO流(保存在计算机中持久的数据)
保存和加载使用技术:
反射
4.案例:
{“长度”:123,“颜色”:read,“score”:100,“房间”:1} 解析
贪吃蛇类
场景还原:
Snake snake=new Snake();
snake.长度=123;
snake.颜色=read;
问题:
1.不知道创建什么类型的对象
2.这个类型有哪些属性 方法 构造方法
5.目的:
生成json
{“长度”:123,“颜色”:read,“score”:100,“房间”:1}
解析json
Snake snake=new Snake();
snake.长度=123;
snake.颜色=read;
半成品软件 可以 在框架基础之上进行开发 简化代码
将类的各个组成部分封装为其他对象 这就是反射机制(描述学生的类 描述英雄的类 描述线程的类 反射就是类 的类)
类中成员变量,成员方法,构造方法,对象就是一个类这个类就可以访问成员变量。
1.可以在程序运行中操作这些对象
2. 可以解耦
ClassLoadder 加载一个类 创建类的类型的东西 class 对象=new class();
1.Class.forName(“全类名”) 将字节码加载进内存
2.类名.Class 通过类名的属性class获取
3.对象.getClass getClass方法在Object中
结论:
同一个字节码文件 在一次程序允许过程中 只会被加载一次 无论通过那种方式方式获取Class对象都是同一个
通过class对象 可以获取类所有成员
1.获取类的所有成员变量
2,获取构造方法
3.获取成员方法
4.获取全类名
案例:
“ Person”类 要求你获取Person中的所有成员
Person person=new Person();
Person.name;
案例:
```package ReflectDemoe;
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;
/*** *
获取类获取成员变量getFieldsgetField(String)getDeclaredFieldsgetDeclaredField(String name)set(Object obj,Object value)参数 前面是对象 后面是变量的值get(Object b)参数是对象setAccessible 暴力反射@author lenovo*/ public class RelfectDemo1 { public static void main01(String[]args) throws ClassNotFoundException {
//1.Class.forName("全类名") Class cls1=Class.forName("ReflectDemoe.Person"); System.out.println(cls1);//class ReflectDemoe.Person //2.类名。class Class cls2=Person.class; System.out.println(cls2);//class ReflectDemoe.Person //3.对象。getClass Person person=new Person(); Class cls3=person.getClass(); System.out.println(cls3);//class ReflectDemoe.Person System.out.println(cls1==cls2);//true System.out.println(cls2==cls3);//true } /** * 成员变量 * 构造方法 * 普通方法 * * * * * @param args * @throws ClassNotFoundException * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalAccessException * @throws IllegalArgumentException */ public static void main02(String[]args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { //1.Class.forName("全类名"); Class clas1=Class.forName("ReflectDemoe.Person"); //2.类对象可以做什么 /** * 1.获取成员变脸 * 获取所有public成员 * Field[]getField();获取所有public 修饰的成员变量 * */ Field [] fields =clas1.getFields(); for(Field field:fields) { //System.out.println(field);//重写 System.out.println(field.getName()); } //根据名字获取一个成员 Field fie=clas1.getField("a"); System.out.println(fie); //设置和获取成员变量的值 Person per=new Person(); per.a=100;//只是为了演示 Object value=fie.get(per); System.out.println(value); //获取成员变量的值 fie.set(per, 1000); Object value1=fie.get(per); System.out.println(value1); //设置成员变量的值 //私有成员无法在类外访问 //反射可以做到访问私有成员 System.out.println("========================="); Field [] fields1 =clas1.getDeclaredFields();//获取所有的成员变量 for(Field field:fields1) { //System.out.println(field);//重写 System.out.println(field.getName()); } Person per1=new Person(12,"小梦"); Field fiel1=clas1.getDeclaredField("age"); fiel1.setAccessible(true);//设置私有成员是否可以访问 暴力反射 Object value2=fiel1.get(per1);//无法获取私有成员 System.out.println("================"); System.out.println(value2); } //获取构造函数:创建对象 /** * Constructor * T newInstance(objcet...inttargs) * 如果使用空参数构造方法 简化 Class对象的newInstance方法 * * * @param args * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException * @throws SecurityException * @throws NoSuchMethodException * @throws InvocationTargetException * @throws IllegalArgumentException */ public static void main03(String[]args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { Class cls1=Class.forName("ReflectDemoe.Person"); //Object person=cls1.newInstance(); //System.out.println(person);//没有参数的创建对象的方式 //使用有参数的构造方法创建对象 //1.获取指定参数类型的构造函数 Constructor constructor=cls1.getConstructor(int.class,String.class); System.out.println(constructor); //2.创建对象 Object person=constructor.newInstance(18,"小梦"); System.out.println(person); //真正摆脱了Person p=new Person(); //强制反射 使用私有构造函数 //constructor.setAccessible(true); //设置构造函数为私有的 目的就是不让你创建 } /** * * Method:方法 function 函数 * getMethod(String name)获取某个方法 Invoke调用 * * * * * * @param args * @throws ClassNotFoundException * @throws SecurityException * @throws NoSuchMethodException * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException */ public static void main(String[]args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class clas1=Class.forName("ReflectDemoe.Person"); //获取方法 Method eat_method=clas1.getMethod("eat"); //分析 获取变量的时候 只需要知道变量名 //获取方法或构造方法 知道方法名和参数(参数列表) Person per=new Person(); eat_method.invoke(per);//调用方法 //如果是有参数的方法 Method eat_method2=clas1.getMethod("eat", String.class); eat_method2.invoke(per, "玉米棒子"); //暴力获取所有修饰的方法 Method[] teMethods=clas1.getDeclaredMethods(); for(Method method:teMethods) { System.out.println(method);//打印所有的方法 System.out.println(method.getName());//打印所有的方法名 method.setAccessible(true);//暴力执行私有成员 } //获取类名 String className=clas1.getName(); System.out.println(className); }}
```案例:
```package ReflectDemoe;
public class Person { public int a; public int b; public String c; public double score; // private double score; //private int age; // private String name;
public int age; public String name; @Override public String toString() { return "Person [a=" + a + ", b=" + b + ", c=" + c + ", age=" + age + ", name=" + name + "]"; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person(int age, String name) { super(); this.age = age; this.name = name; } public Person() { super(); } public void eat() { System.out.println("米西米西"); } public void eat(String foodName) { System.out.println("米西米西"+foodName); }}
package ReflectDemoe; /****
JSON(字符串) 用来描述对象{“属性”:“值”,“属性”:“值”,“属性”:“值”,“属性”:“值”}{“age”:“18”,“name”:“小梦”,“score”:“99.9”}把对象保存为串 把串解析为对象通用的功能 工具 静态的方法 类 JsonHelper或JsonHandler1.对象-》字符串2.字符串-》对象 根据JSON串 特性 给对象赋值@author lenovo*/
public class Test1 { public static void main(String[]args) throws IllegalArgumentException, IllegalAccessException { Person person=new Person(12,“小梦”); person.a=1000; person.b=200; person.c=“哈哈哈”; String json= JsonHelper.ObjectToString(person);
System.out.println(json);//只获取了私有的成员 }}
package ReflectDemoe;
import java.lang.reflect.Field; import java.text.MessageFormat;
/** *
Json解析和生成Json@author lenovo*/ public class JsonHelper { public static String ObjectToString(Object obj) throws IllegalArgumentException, IllegalAccessException { //思路: //反射该对象所有的属性 根据名称拼接字符串 //拼接字符串StringBuilder StringBuilder builder=new StringBuilder(32); //1.创建字符串拼接对象 Class cls1=obj.getClass(); Field[]files=cls1.getFields();//获取对象类型 //3.获取所有字段 //1.拼接花括号 builder.append("{"); for(Field field:files) { //一个属性拼接一次“属性":“值”, //{0}占位符 String str=MessageFormat.format(”"{0}":"{1}",", field.getName(),field.get(obj)); builder.append(str); } builder.setLength(builder.length()-1); //去掉最后的逗号 builder.append("}"); //最后凭借末尾的花括号 return builder.toString();
}}
```案例:
```package ReflectDemoe;
import java.io.File; import java.lang.reflect.Field; import java.text.MessageFormat;
/**
Json解析和生成Json{“属性”:“值”,“属性”:“值”,“属性”:“值”,“属性”:“值”,“属性”:“值”}{“age”:“18”,“name”:“小梦”,“score”:“99.9”}@author XuYang*/ public class JsonHelper {
/** * 对象转字符串 * @param obj * @return * @throws IllegalArgumentException * @throws IllegalAccessException */ public static String objectToString(Object obj) throws IllegalArgumentException, IllegalAccessException{ //思路:反射该对象所有的属性 根据名称 拼接字符串 //拼接字符串 StringBuilder StringBuilder builder=new StringBuilder(32); //1.创建字符串拼接 Class cls1=obj.getClass(); //2.获取对象类型 Field [] files=cls1.getFields(); //3.获取所有字段 //1)拼接花括号 builder.append("{"); for (Field field : files) { //一个属性拼接一次"属性":"值", //{0}占位符 String str=MessageFormat. format("\"{0}\":\"{1}\",",field.getName(),field.get(obj)); builder.append(str); } builder.setLength(builder.length()-1); //去掉最后一个逗号 builder.append("}"); //最后拼接末尾的花括号 return builder.toString(); } /** * 字符串读出来 赋值给Person对象 * 疑问:对象不知道类型 还需要创建 因为要赋值 * 1.不知道类型 用newInstance创建 * 2.但是 newInstance属于Class的 * @throws IllegalAccessException * @throws InstantiationException * @throws SecurityException * @throws NoSuchFieldException */ public static <T> T stringToObject(String json,Class<T> cls1) throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException{ T instance= cls1.newInstance();//创建泛型对象 //1创建对象 //"age":"18","name":"小梦","score":"99.9" // age 18 i i+1 // name 小梦 i i+1 //score 99.9 json=json.replace("{", "").replace("}", "").replace("\"", "");//或括号替换为空 //System.out.println(json); //:分割的是 成员变量名:成员变量值 前 age 后 18 //,分割的是 分割两个成员变量age 18 String [] strArr= json.split(",|:");// //2.解析Json 给对象的每一个成员变量赋值 //使用for循环遍历 i+=2 两个是一组 a 100 i属性 i+1值 for (int i = 0; i < strArr.length; i+=2) { //获取成员变量的名字 String fieldName=strArr[i];//a b c name age //获取成员遍历 设置成员遍历值得时候 field.set(obj,值) Field field=cls1.getField(fieldName);//成员遍历 String value=strArr[i+1]; //赋值 //分析:value是字符串 成员变量是int double float String if ("int".equalsIgnoreCase(field.getType().toString())) { //如果成员变量得类型 getType 是 int field.setInt(instance, Integer.parseInt(value)); } else if ("double".equalsIgnoreCase(field.getType().toString())) { //如果成员变量得类型 getType 是 int field.setDouble(instance,Double.parseDouble(value)); } else if ("class java.lang.String".equalsIgnoreCase(field.getType().toString())) { field.set(instance, value); } else { //自定义类型和普通类型转换 //field.set(obj, value); field.set(instance,field.getType().newInstance()); } } return instance; }}
package ReflectDemoe; /****
JSON(字符串) 用来描述对象{“属性”:“值”,“属性”:“值”,“属性”:“值”,“属性”:“值”}{“age”:“18”,“name”:“小梦”,“score”:“99.9”}把对象保存为串 把串解析为对象通用的功能 工具 静态的方法 类 JsonHelper或JsonHandler1.对象-》字符串2.字符串-》对象 根据JSON串 特性 给对象赋值@author lenovo*/
public class Test1 { public static void main(String[]args) throws IllegalArgumentException, IllegalAccessException, InstantiationException, NoSuchFieldException, SecurityException { // Person person=new Person(12,“小梦”); // person.a=1000; // person.b=200; // person.c=“哈哈哈”; // String json= JsonHelper.ObjectToString(person); // // System.out.println(json);//只获取了私有的成员 Person person= JsonHelper.stringToObject("{“a”:“100”,“b”:“200”,“c”:“哈哈哈”,“age”:“12”,“name”:“小梦”}",Person.class); System.out.println(person.a);
System.out.println(person.age); System.out.println(person.name); }}
package ReflectDemoe;
public class Person { public int a; public int b; public String c; public double score; // private double score; //private int age; // private String name;
public int age; public String name; @Override public String toString() { return "Person [a=" + a + ", b=" + b + ", c=" + c + ", age=" + age + ", name=" + name + "]"; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person(int age, String name) { super(); this.age = age; this.name = name; } public Person() { super(); } public void eat() { System.out.println("米西米西"); } public void eat(String foodName) { System.out.println("米西米西"+foodName); }}
```e String name;
public int age; public String name; @Override public String toString() { return "Person [a=" + a + ", b=" + b + ", c=" + c + ", age=" + age + ", name=" + name + "]"; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person(int age, String name) { super(); this.age = age; this.name = name; } public Person() { super(); } public void eat() { System.out.println("米西米西"); } public void eat(String foodName) { System.out.println("米西米西"+foodName); }}
```