什么是反射
反射机制使在程序运行的状态中,对于任意一个类,都能获取这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性。
这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射的作用
- 可以实现简单的反编译,获取类中的属性和方法等基本信息, .class->java
- 通过反射机制获取类的属性,方法等。
在使用eclipse时,通过对象引用.的方式,eclipse就会将这个对象中的所有属性和方法展示出来,这个就是利用反射机制。其实反射应用最多的地方就是将来要学习的框架,例如 spring、spring MVC、Mybatis等等。
反射的优点
提高程序的灵活性和扩展性。使用反射机制后,程序在创建对象的时候不用使用new关键字写死在程序中了,而是从配置文件中进行读取,这样可以提高程序的灵活性
Class对象
在类加载器将.class文件读取到内存中的时候,jvm会创建这个.class文件对象,并且只创建一个存放到jvm的方法区内存中,在java.lang包下有个Class类,这个类就是 .class文件的对象类型,任何类在被使用 时,都会创建这个类的Class对象。除此之外,在java.lang.reflect 包下面的类也跟反射有关。
创建一个Person类:
package com.reflect;
public class Person {
private String name;
public static int age;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name) {
super();
this.name = name;
}
public String getName(int a) {
return name;
}
public void setName(String name,int b) {
this.name = name;
}
public void sing(String s,String t) {
System.out.println("唱歌");
}
private String pig() {
return "123";
}
}
获取Person类的Class对象有三种方式
package com.reflect;
/*
* 获取Person类的Class对象的有三种方式
*/
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
//第一种方式
//c1引用对象代表整个 Person类
Class clazz1 = Class.forName("Person");
//第二种方式
//java中每个类型都有class属性
Class c2 =Person.class;
//第三种方式
//java语言中任何一个java对象都有getClass方法
Person p = new Person();
Class c3 = p.getClass();
}
}
使用反射类创建Person类的对象
newInstance()
package com.reflect;
/*
* 使用反射创建类的对象
*/
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException {
try {
Class clazz = Class.forName("com.reflect.Person");
Object o = clazz.newInstance();
System.out.println(o);
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
使用反射获取类的属性
package com.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/*
使用反射获取类中的属性
*/
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException {
Class c = Class.forName("com.reflect.Person");
Field[] field = c.getDeclaredFields();
for(Field f:field) {
//获取属性变量名
System.out.println(f.getName()); //name
//获取访问权限修饰符的int值
System.out.println(f.getModifiers());//2
//将int值转换为访问权限修饰符
System.out.println(Modifier.toString(f.getModifiers()));//private
//获取属性 类型的class对象
Class type = f.getType();
System.out.println(type.getName());//java.lang.String
//不带包名的类名
System.out.println(type.getSimpleName());//String
}
}
}
使用反射反编译
package com.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Test04 {
public static void main(String[] args) throws ClassNotFoundException {
Class c = Class.forName("com.reflect.Person");
//Class c = Class.forName("java.lang.Integer");
StringBuilder sb = new StringBuilder(200);
sb.append(Modifier.toString(c.getModifiers())+" class "+c.getSimpleName()+'\n');
sb.append("{"+"\n");
Field[] field = c.getDeclaredFields();
for(Field f:field) {
sb.append(Modifier.toString(f.getModifiers())+" ");
sb.append(f.getType().getSimpleName()+" ");
sb.append(f.getName()+";");
sb.append("\n");
}
sb.append("}");
System.out.println(sb.toString());
}
}
使用反射获取类中指定属性并赋值
package com.reflect;
import java.lang.reflect.Field;
/*
* 使用反射获取类中指定的属性并赋值
*/
public class Test05 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
Class c1 = Class.forName("com.reflect.Person");
//获取类中指定的属性并赋值
Field f = c1.getDeclaredField("name");
//创建对象
Object o = c1.newInstance();
//从外部打破封装性
f.setAccessible(true);
//给o对象上的name属性赋值为zhoujian
f.set(o, "zhoujian");
//获取o对象上的name属性值
System.out.println(f.get(o));
}
}
使用反射获取类中的方法
下面程序将.class文件中的方法反编译并打印出来。
package com.reflect;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/*
使用反射获取类中的方法
*/
public class Test06 {
public static void main(String[] args) throws ClassNotFoundException {
Class c1 = Class.forName("com.reflect.Person");
Method[] method = c1.getDeclaredMethods();
for(Method m:method) {
//方法修饰符
System.out.print(Modifier.toString(m.getModifiers())+" ");
//方法的返回值类型
System.out.print(m.getReturnType().getSimpleName()+" ");
//方法名
System.out.print(m.getName()+" ");
//方法参数
Class[] c = m.getParameterTypes();
for(Class p:c) {
System.out.println(p.getSimpleName());
}
}
}
}
使用反射类调用类中的方法
package com.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/*
* 使用反射调用类中的方法
*/
public class Test09 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Class c = Class.forName("com.reflect.Person");
//获取方法
Method method = c.getDeclaredMethod("setName", String.class,int.class);
//创建对象
Object o = c.newInstance();
Object result = method.invoke(o, "a",10);
System.out.println(result);
}
}
使用反射获取构造方法
package com.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
/*
* 使用反射 获取构造方法
*/
public class Test10 {
public static void main(String[] args) throws ClassNotFoundException {
Class c = Class.forName("com.reflect.Person");
Constructor[] con = c.getConstructors();
for(Constructor c1:con) {
//获取修饰符
System.out.print(Modifier.toString(c1.getModifiers())+" ");
//获取方法名
System.out.print(c1.getName()+" ");
//获取方法参数
Class[] Para = c1.getParameterTypes();
for(Class pa:Para ) {
System.out.println(pa.getSimpleName()+" ");
}
}
}
}