反射
1.获取class对象
eclipse按ctrl+l不会补全新建对象的变量名,需要手动补全;
-
Class的静态方法forName
仅当给出完成类报名时使用,因为如果
类包名
错误会报错;try{ Class forName = Class.forName("java.lang.String"); }catch(ClassNotFoundException e){ }
-
类的class属性[推荐]
代码更安全性能更好
class clazz = String.class;
-
Object类里的getClass()方法
String string= "x"; Class clazz = string.getClass();
2.新建对象
-
java不推荐使用
try{ Object object = clazz.newInstance(["参数1","参数2"]); }catch{}
-
java推荐使用
try{ Object object = clazz.getDeclaredConstructor().newInstance(["参数1","参数2"]); }catch{}
3.获取class信息[了解]
-
获取修饰符[了解]
-
返回值是修饰符值相加
int x = clazz.getModifiedrs();
-
列表
修饰符 值 ABSTRACT
1024
FINAL
16
INTERFACE
512
NATIVE
256
PRIVATE
2
PROTECTED
4
PUBLIC
1
STATIC
8
STRICT
2048
SYNCHRONIZED
32
TRANSIENT
128
VOLATILE
64
-
-
获取类名
-
获取完整包类名
String name = clazz.getName();
-
获取类名
String name = clazz.getSimpleName();
-
-
获取包名
Stirng name = clazz.getPackName();
-
获取超类(父类)
Class sclazz = clazz.getSuper().getName();
4.获取class属性
getDeclarredFields/Methods/Constructors是获取私有数据,不加不能获取私有数据
-
获取属性(变量)数组
Field[] x= clazz.getFields();
-
已知属性名获取[不常用]
Field x =clazz.getFields("属性名");
-
-
获取方法数组
Method[] y = clazz.getDeclaredMethods();
-
已知方法名和类型获取[不常用]
Method y = clazz.getDeclaredMethods("方法名",参数类型1.class,参数类型2.class);
-
-
获取构造方法数组
Constructors[] z = clazz.getDeclaredConstructors()[.getName];
-
已知有参构造器获取[不常用]
Constructors z = clazz.getDeclaredMethods(参数类型1.class,参数类型2.class);
-
5.获取修改属性信息
-
获取名称
String name = x/y/z.getName();
-
获取修饰符
int a = x/y/z.getModifiders();
-
设置私有属性可被修改/访问
x/y/z.setAccessible(true);
-
获取属性类型
Class type= x.getType()[.getName()];
-
属性名
-
获取
Object oject = [(类型)]x.get(要获取的对象);
-
赋值
x.set(要被赋值的对象,"值");
-
-
获取参数列表类型
Class[] Parameter = y/z.getParameterTypes();
-
获取返回值类型
Class return = y/z.getReturnType();
-
获取抛出异常的类型
Class exception = y/z.getExceptionType();
-
执行方法
x.invoke(要被执行的方法,"参数1","参数2");
6.事例
模仿springIOC功能
-
Father.java
private String name; private Integer age; private String sex; get/set/构造方法/toString;
-
MySpring.java
public Object getBean(String className) { Object object = null; Scanner input = new Scanner(System.in); System.out.println("请给"+className+"类的对象赋值"); try { //1.getBean Class<?> clazz = Class.forName(className); object = clazz.newInstance(); //2.依赖注入:通过成员变量生成set方法 Field[] fields = clazz.getDeclaredFields(); for(Field field :fields) { //(1.)拼接成员变量变成set方法 String fieldName = field.getName(); String upperCase = fieldName.substring(0, 1).toUpperCase(); String substring = fieldName.substring(1); StringBuilder setMethodName = new StringBuilder("set"); setMethodName.append(upperCase); setMethodName.append(substring); //(2.)通过拼接到的set方法名获取set方法对象 Class<?> Fieldtype = field.getType(); Method method = clazz.getDeclaredMethod(setMethodName.toString(), Fieldtype); method.setAccessible(true); System.out.println("请给"+setMethodName+"赋值"); String value = input.nextLine(); //(3.)采用newInteger(String)的方式转换格式 Constructor<?> fieldConstructor = Fieldtype.getDeclaredConstructor(String.class);//获取参数类的(string)构造方法 Object value2 = fieldConstructor.newInstance(value);//通过构造方法新建对象 method.invoke(object, value2); } } catch (Exception e) { e.printStackTrace(); } return object; }
-
test.java
public static void main(String[] args) { MySpring spring = new MySpring(); Father father = (Father)spring.getBean("Other.反射.untity.Father"); System.out.println(father); }