java高级之反射
1.理解反射:
【其就是在运行时,它是把类中成员抽取为其他类对象的过程】
2.获取反射Class的三种方式:
【获取之前首先要创建一个类对象,这里就叫做 xw.Class】
其一:
通过Class.forName的方式获取:
及
Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
其二:
通过类名.class 方式获取:
及
Class<xw> xwClass = xw.class;
其三:
通过对象.getClass();方式获取:
及
xw xw = new xw();
Class<? extends com.ssm.entity.fanshe.xw> aClass2 = xw.getClass();
3.通过反射类获取对象
【这里我们就直接用第一种方式获取对象】
【注:通过Class类对象,调用newInstance()】
//通过反射字解码获取第一种方式
Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
//通过反射获取类对象,其他两种方式以此类推
xw o = (xw) aClass.newInstance();
System.out.println(o);
【还是以第一种方式或取对象】
【这里通过 getDeclaredFields() 的方法可以获取本类中所有的属性成员对象(包括公有、私有)】
//通过反射字解码获取第一种方式
Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
//通过反射获取类对象,其他两种方式以此类推
xw o = (xw) aClass.newInstance();
System.out.println(o);
//通过反射过去类属性对象,其返回的是一个数组
//获取本来中所有的类属性对象
Field[] declaredFields = aClass.getDeclaredFields();
for (Field jk:declaredFields) {
System.out.println("我可以获取到本类中所有的类属性:"+jk);
}
【这里通过 getFields() 的方法可以获取本类以及父类中的公有属性成员对象(注:不包括私有)】
//获取本类中所有的公有的类属性对象(包括继承的父类公有类属性)
Field[] fields = aClass.getFields();
for (Field jk2:fields) {
System.out.println("获取的是所有公共类属性:"+jk2);
}
【这里通过 getDeclaredField("age") 的方法可以获取本类中指定的单个属性成员对象】
//获取本类中指定的单个类属性
Field age = aClass.getDeclaredField("age");
System.out.println("获取的是指定的单个类属性:"+age);
这里咱们首先通过反射的方式为属性成员对象设置参数
在此之前我们所获取的成员对象都是空值
Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
xw o = (xw) aClass.newInstance();
//通过反射来set成员属性值
Field ages = aClass.getDeclaredField("age");
ages.set(o,66);
System.out.println("通过反射设置的属性:"+o);
这里打印结果肯定会报错:
Exception in thread "main" java.lang.IllegalAccessException: Class com.ssm.entity.fanshe.demo1 can not access a member of class com.ssm.entity.fanshe.xw with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Field.set(Field.java:761)
at com.ssm.entity.fanshe.demo1.main(demo1.java:33)
报错的原因是因为咱们设置的成员对象如果是私有的,它不允许访问,【非法访问 】
这里只需要加上 变量.setAccessible(true); 即可访问私有成员对象即:【授权】
//通过反射设置set属性
Field ages = aClass.getDeclaredField("age");
ages.setAccessible(true);
ages.set(o,66);
System.out.println("通过反射设置的属性:"+o);
打印结果为:
通过反射设置的属性:xw{name = null, age = 66, hobber = null, higeh = null}
5.2 getAnnotation(注解.class):获取属性上的注解对象
这里咱们首先肯定要去自定义一个注解:并且在其中定义一个属性,以便演示 getAnnotation(注解.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE})
public @interface Myzhu {
public String value();
}
【 如果不清楚怎么自定义注解,可以阅读我上一篇文章写的 java高级之注解】
自定义后,加在类上
随后其直接通过 getAnnotation(注解.class) 就可以获取到注解属性
//通过反射获取注解对象
Myzhu annotation = aClass.getAnnotation(Myzhu.class);
System.out.println(annotation);
6.1 getDeclaredMethods()
通过 getDeclaredMethods() 方法可以获取本类中所有的方法类对象(包括公有、私有、get、set方法)
Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
xw o = (xw) aClass.newInstance();
//通过反射获取本类中所有的方法类对象(包括公有、私有、get、set方法)
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println("获取的是本类中所有的方法"+declaredMethod);
}
6.2 getDeclaredMethod()
通过 getDeclaredMethod() 方法可以获取本类中指定的方法类对象
* 值得注意的是,指定获取单个方法类对象需要填写 (String name,Class<?>... param...) 等可变参数
eg1:
Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
xw o = (xw) aClass.newInstance();
//通过反射获取本类中指定的方法类对象
Method xw01 = aClass.getDeclaredMethod("xw01");
Object invoke = xw01.invoke(o);
System.out.println(invoke);
System.out.println("通过反射获取本类中指定的方法类对象:"+xw01);
eg2:
//增加可变参数演示
Method xw02 = aClass.getDeclaredMethod("xw02",Integer.class);
xw02.invoke(o,666);
类中方法:
public String xw02(Integer xw){
System.out.println("----xw02-----");
return "返回了公有方法xw02";
}
如果要指定获取私有方法,那就多添加一个 setAccessible(true);
及
Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
xw o = (xw) aClass.newInstance();
Method xw03 = aClass.getDeclaredMethod("xw03", Integer.class);
xw03.setAccessible(true);
xw03.invoke(o,555);
【*类中方法中参数定义的什么数据类型,那么使用反射获取类中指定的方法类对象时,可变参数就填什么数据类型】
6.3 getMethods()
//通过反射获取本类及父辈中的所有方法(真的是指所有,本类及父辈的方法)
Method[] methods = aClass.getMethods();
for (Method method : methods) {
System.out.println("通过反射获取本类及父辈中的所有方法:"+method);
}
7.1 getConstructors()
Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
xw o = (xw) aClass.newInstance();
//通过反射获取本类中所有的构造对象
Constructor<?>[] constructors = aClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println("通过反射获取本类中所有的构造对象:"+constructor);
}
7.2 getConstructors()
【值得注意的是,这个方法与之前的不同,它只能获取本类中所有的公共构造对象,不再是可以获取本类以及父类的构造对象】
Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
xw o = (xw) aClass.newInstance();
//通过反射获取本类中所有的公共构造对象
Constructor<?>[] constructorss = aClass.getConstructors();
for (Constructor<?> constructor : constructorss) {
System.out.println("通过反射获取本类中所有的公共构造对象:"+constructor);
}
//只获取无参构造对象
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
System.out.println("只获取无参构造对象:"+declaredConstructor);
//指定获取有参构造对象
Class<jk> jkClass = jk.class;
Constructor<com.ssm.entity.fanshe.jk> declaredConstructor1 = jkClass.getDeclaredConstructor(String.class);
//获取私有构造对象,这里依然要授权,又称暴力反射
declaredConstructor1.setAccessible(true);
com.ssm.entity.fanshe.jk NineLimit = declaredConstructor1.newInstance("取九极致之术");
System.out.println(NineLimit);
打印结果:
jk{name = 取九极致之术}
class文件:
class jk{
private String name;
//公有无参
public jk() {
}
//公有有参
public jk(String name) {
this.name = name;
}
//私有有参
private void jk(String name){
this.name = name;
}
}
以上便是java高级反射的内容,如有漏缺,请在下方评论区中留言,我会及时补充