反射
1.反射的介绍
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制,很多优秀的开源框架都是通过反射完成的。
Java反射机制,可以实现以下功能:
①在运行时判断任意一个对象所属的类;
②在运行时构造任意一个类的对象;
③在运行时判断任意一个类所具有的成员变量和方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理;
2.获取Class对象
Class 对象
在类加载到内容中时就有了表示这个类型的Class对象
Class对象是唯一的,不会改变的
private int a;
private String Uname;
private String Upwd;
public Demo(){
}
public Demo(double a){
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
@Override
public String toString() {
return "Demo{" +
"a=" + a +
", Uname='" + Uname + '\'' +
", Upwd='" + Upwd + '\'' +
'}';
}
private Demo(int a){
this.a=a;
}
public Demo(String a){
}
public Demo(String uname, String upwd) {
Uname = uname;
Upwd = upwd;
}
public String getUname() {
return Uname;
}
public void setUname(String uname) {
Uname = uname;
}
public String getUpwd() {
return Upwd;
}
public void setUpwd(String upwd) {
Upwd = upwd;
}
public void a(){
System.out.println("你好");
}
public void b(){
System.out.println("世界");
}
private void c(){
System.out.println("哈哈");
}2.1:对象.class
Demo demo=new Demo();
Class<?> c1=demo.getClass();
System.out.println(c1.getName());2.2:类.class
Class<?> c2=Demo.class; System.out.println(c2.getName());
2.3:Class.forName()-->推荐使用这种方式
Class<?> c3=Class.forName("com.zh.reflect");
System.out.println(c3.getName());2.4根据子类的对象获取父类
Class c4=c3.getSuperclass(); System.out.println(c4.getName());
2.5基本数据类型与包装类的对比
//基本数据类型的Class对象 System.out.println(int.class); //基本数据类型的包装类都有一个TYPE System.out.println(Integer.TYPE); System.out.println(Integer.TYPE==int.class);
可以说明Class的对象是唯一的,不会改变
3.获得修饰符
返回此类或接口的Java语言修饰符,以整数编码。
Class<?> clz=Class.forName("com.zh.reflect.Demo");
int n=clz.getModifiers();
System.out.println(Modifier.toString(n));4.创建对象
4.1获得构造器
根据Class对象,我们可以获得构造器,为实例化对象做准备。
getConstructor()--->获得public权限的构造器 返回一个Constructor对象
getConstructors()--->获得所有public权限的构造器,返回一个Constructor数组
getDeclaredConstructor()--->获得所有权限的构造器 返回一个Constructor对象
getDeclaredConstructors()--->获得所有权限的构造器 返回一个Constructor数组
Constructor<?> constructor = clz.getConstructor();//不给参数,默认调用参数空的构造器,如果没有,会报异常
System.out.println(constructor);
constructor=clz.getConstructor(String.class);--->获得一个带(String)的构造器
System.out.println(constructor);
Constructor<?>[] constructors=clz.getConstructors();
for(Constructor<?> c:constructors){
System.out.println(c);
}
Constructor<?> declaredConstructor = clz.getDeclaredConstructor(int.class);//获得所有权限的带int参数的构造器
System.out.println(declaredConstructor);
Constructor<?>[] constructors=clz.getDeclaredConstructors();//获得所有权限的所有构造器
for(Constructor<?> c:constructors){
System.out.println(c);
}4.2实例化对象
4.2.1使用newInstance()
Class类中newInstance方法 内部创建对象时候默认调用空构造,没有空构造方法则抛出异常InstantiationException
Class<?> c= Class.forName("com.zh.reflect.Demo");
Demo demo = (Demo) c.newInstance();//实例化一个Demo类的对象
demo.setA(1);
demo.setUname("aaa");
demo.setUpwd("bbb");
System.out.println(demo);4.2.2获取构造器,在调用构造器的newInstance()方法,并赋实参。
如果遇到private权限的构造器,使用constructor.setAccessible(true)方法忽略权限
Constructor constructor=c.getConstructor(String.class,String.class);//获取构造器
Demo demo=(Demo)constructor.newInstance("aaaa","cccc");//创建对象 指定使用这种构造器 赋初值
System.out.println(demo);
Constructor<?> constructor = c.getDeclaredConstructor(int.class);//获得带int类型参数的构造器
int modifiers = constructor.getModifiers();
System.out.println(Modifier.toString(modifiers));//输出修饰符
constructor.setAccessible(true);//如果是私有的内容,使用前忽略权限
Demo demo = (Demo)constructor.newInstance(3);
System.out.println(demo);5.获得方法
getMethod(...)-->获得指定名字的公有方法 返回Method
getMethods()-->获得所有公有方法 返回Method [ ]数组
getDeclaredMethod(...)-->获得指定名字的所有修饰符的方法 返回Method
getDeclaredMethods()-->获得所有方法 返回Method [ ]数组
Demo demo=new Demo();
Class<?> classz=Class.forName("com.zh.reflect.Demo");
Method a = classz.getMethod("a");//获得叫 a的公有方法
System.out.println(a.getName());//获得方法名调用方法 Object invoke(Object obj, Object... args)
成员方法 ->对象
静态方法 ->对象|类
a.invoke(demo);
如果是调用私有方法,一定也得调用a.setAccessible(true),忽略方法权限
Demo demo=new Demo();
Class<?> classz=Class.forName("com.zh.reflect.Demo");
Method c = classz.getDeclaredMethod("c");
c.setAccessible(true);
c.invoke(demo);6.获得属性
getField(....)-->获得指定的公有属性 返回Field
getFields()-->获得所有的公有属性 返回Field [ ] 数组
getDeclaredField(...)-->获得指定所有修饰符的属性 返回 Field
getDeclaredFields(...)-->获得所有属性 返回 Field [ ] 数组
与方法类似 访问私有属性时 也要调用setAccessible()方法 忽略权限
Class classz=Class.forName("com.zh.reflect.Demo");
Demo demo =(Demo) classz.getConstructor(String.class, String.class).newInstance("aaa", "bbb");
Field uname = classz.getDeclaredField("Uname");
uname.setAccessible(true);//忽略权限
uname.set(demo,"aaa");//设置属性
System.out.println(uname.get(demo));//输出这个对象的所获得的这个属性的值7.数组
操作数组需要借助Array类
String[] arr = (String[]) Array.newInstance(String.class,5); System.out.println(arr.getClass().isArray()); //设置值 Array.set(arr,0,"胡歌"); //获取值 System.out.println(Array.get(arr,0)); System.out.println(Arrays.toString(arr));
上海得物信息集团有限公司公司福利 1166人发布
查看11道真题和解析