粘贴拓哥的小白板
如何操作类中的方法:写一个小程序边试边思考
Class类中的方法
Method m = class.getMethod(“方法名”,Class…参数类型); 获取公有的方法(自己类+父类)
Method[] = clazz.getMethods(); 获取所有的方法(公有 自己+父类)
Method = getDeclaredMethod(“方法名字”,参数类型的class…) 获取一个方法(自己类 公有 私有)
Method[] = getDeclaredMethods(); 获取全部的方法(自己类 公有 私有)
获取构造方法
Constructor = clazz.getConstructor(Class…参数类型)
Constructor[] cons = clazz.getConstructors();
clazz.getDeclaredConstructor();
clazz.getDeclaredConstructors();
Method类中的常用
int mm = m.getModifiers();//获取方法的修饰符(权限+特征)
Class mrt = m.getReturnType();//获取返回值数据类型
String mn = m.getName();//获取方法的名字
Class[] mpts = m.getParameterTypes();//获取方法参数列表的类型
Class[] mets = m.getExceptionTypes();//获取方法抛出异常的类型
如何操作方法:调用方法,让他执行一次
Object result = invoke(对象,执行方法需要传递的所有参数…);—->是Object类下的动态列表
若方法是私有的方法,不允许操作
可以设置setAccessable(true),设置方法使用权,给予准入权限
Constructor类中的常用方法
con.getModifiers();
con.getName();
con.getParameterTypes();
con.getExceptionTypes();
如何操作构造方法,让它执行一次来创建对象:
Object = newInstance(执行构造方法时的所有参数);
con.setAccessible(true);
【实例】
String——>类——>创建一个对象
设计一个方法,给一个字符串(类)返回一个对象,对象里面还有属性值
设计一个小工具,为了替代我们自己创建对象的过程
这个方法传递一个字符串,帮我们创建一个对象,同时还能将对象内的所有属性赋值
——思考——分析——
考试系统:Question类型的对象
ATM系统:User类型的对象
Question和User类型都是我们自定义的,
它们两个类的目的不是为了做什么逻辑功能
它们只为了存储某些值,看似是个对象,但更像是个容器
MVC封层架构:<br /> M: Service做业务逻辑(例如判断、比较) <br />Dao负责在文件里或数据库里做真实操作数据<br /> 传输和存储的实体对象:domain/javaBean/po/vo/pojo
引申:
//Spring开源框架 //AOP(面向切面)
IOC控制反转(Inversion Of Control) 对象的控制权反转
DI依赖注入(Dependency Injection) 对象的控制权是别人的 他在创建对象的同时 帮我们自动注入属性值
【代码】
package ioc;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Scanner;
public class MySpring {
//设计一个方法,帮我控制对象的创建
// 1.是否需要参数?--->字符串String表示类全名
// 2.是否需要返回值?-->Object类型对象
public Object getBean(String className){
Object obj = null;
Scanner input = new Scanner(System.in);
System.out.println("请给"+className+"类的对象赋值");
try {
//1.获取方法传递进来的参数对应的类
Class clazz = Class.forName(className);
//2.通过clazz创建一个对象
obj = clazz.newInstance();
// 在这里做一个自动的DI(依赖注入),注入对象中的所有属性值
// 找寻每一个不同属性对象对应的set方法进行赋值
// 通过拼接字符串的方式处理属性的名字
//3.通过clazz找到所有的私有属性-->获取每一个属性名字-->用来处理set属性名
Field[] fields = clazz.getDeclaredFields();
for(Field field :fields){
// 获取属性名字
String fieldName = field.getName();
// 手动拼接属性对应的方法名
String firstLetter = fieldName.substring(0,1).toUpperCase(); //属性名中的首字母变大写
String otherLetters = fieldName.substring(1); //属性名里,除首字母外的其他字母
StringBuilder setMethodName = new StringBuilder("set");
setMethodName.append(firstLetter);
setMethodName.append(otherLetters);
// 获取field对应的属性类型-->为了找寻set方法之后,传递参数使用
Class fieldClass = field.getType();
// 通过处理好的set方法名,找寻类中的set方法
Method setMethod = clazz.getMethod(setMethodName.toString(),fieldClass);
// 找到setMethod后,执行时,属性就赋值成功
System.out.println("请给"+fieldName+"属性提供值");
String value = input.nextLine();
/*
需要执行属性对应的set方法给属性赋值,到此,方法就结束了。
属性的值目前是通过接收而来的(Scanner或从文件内读取过来),全都是String类型的
我们在执行set方法的时候,方法需要的值不一定都是String类型,而是属性类型的值
我们如何将所有的String类型的值都转化-->成属性类型的值?
eg.包装类Integer-->在8个包装类中,有7个都含有带String类型的构造方法
除了Char类型不可以,其他7个都可以传String类型作为参数:
new Integer(String) new Float(String) new String(String)
(如果属性是char类型、数组类型,这里需要先判断,并给他们做处理)
可以利用包装类带String的构造方法来处理,找的是属性类型对应的带String参数的构造方法
*/
Constructor con = fieldClass.getConstructor(String.class);
setMethod.invoke(obj,con.newInstance(value)); // 值的类型是属性的类型,所以如果是直接传value作为参数则会产生错误-->不同的属性类型
}
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
}