反射
反射就是把Java类中的各种成份映射成相应的Java类,例如Method类、Constructor类、Field类、Package类等
反射构造方法
Method: Class<T>类
Constructor<T> getConstructor(Class<?>... parameterTypes) //返回此字节码所表示的类的指定的public构造器
Constructor<?>[] getConstructors() //所有public修饰的构造器
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) //返回指定的构造器对象(包括private)
Constructor<?>[] getDeclaredConstructors() //获得所有声明的构造函数
T newInstance() //创建对象,调用不带参数的构造函数
Method: Constructor<T>类
T newInstance(Object... obj) //创建对象,obj为构造方法接收的参数
import java.lang.reflect.Constructor;
/**
通过Class对象,反射获取Constructor对象
使用Constructor对象的newInstance(Object... obj)方法创建对象
*/
class ConstructorDemo
{
public static void main(String[] args) throws Exception
{
Constructor<String> con = String.class.getConstructor(StringBuffer.class);
String str = con.newInstance(new StringBuffer("abc"));
System.out.println(str);
}
}
反射字段
Method: Class<T>类
Field getField(String name) //获取指定属性的Field
Field[] getFields() //获取所有属性的Field,返回Field[]
Field getDeclaredField(String name) //获取指定属性的Field(包括private修饰的属性)
Method: Field类
getXxx(Object obj) //获取obj对象中该Field的属性值,此处的Xxx对应8种基本类型,如果该属性的类型是引用类型则取消get后面的Xxx
setXxx(Object obj, Xxx val) //将obj对象的该Field设置成val值。此处Xxx对应8种基本类型,如果该属性是引用则取消set后面的Xxx
import java.lang.reflect.*;
/**
通过反射方式访问属性值
*/
class Person
{
private String name;
public int age;
}
public class FieldTest
{
public static void main(String[] args) throws Exception
{
Person p = new Person();
//获取Person类对应的字节码
Class<Person> personClazz = Person.class;
Field ageField = personClazz.getField("age");
ageField.setInt(p , 30);
System.out.println(ageField.getInt(p));
//获取Person类中名为name的属性,使用getDeclaredField可以获取private修饰的属性
Field nameField = personClazz.getDeclaredField("name");
//设置通过反射访问该Field时取消访问权限检查:暴力反射
nameField.setAccessible(true);
//调用set方法为p对象的指定Field设置值
nameField.set(p , "zhangsan");
//调用get方法获取p对象中的name属性值
System.out.println(nameField.get(p));
}
}
反射方法
Method: Class<T>类
Method getMethod(String name, Class<?>... parameterTypes) //如获取show(String str, int i)方法:getMethod(show, String.class, Integer.class)
Method[] getMethods() //获取所有方法实例到Method[]中
Method getDeclaredMethod(String name, Class<?>... parameterTypes)
Method[] getDeclaredMethods()
Method: Method类
Object invoke(Object obj, Object... args) //obj是执行方法的对象,args是执行方法时传入方法的实参
注意:
如果执行的是静态方法,obj为null
如果没有参数,因为args为可变参数,可以不填,所以无参数时不需要填参数
import java.lang.reflect.Method;
/**
反射的方式调用方法
*/
class Person
{
private void show()
{
System.out.println("hello");
}
public void show(String str1, String str2)
{
System.out.println(str1+str2);
}
public static void show(int i)
{
System.out.println(i);
}
}
class MethodReflectTest
{
public static void main(String[] args) throws Exception
{
Person p = new Person();
Class<?> clazz = p.getClass();
//调用public方法
Method showMethod2 = clazz.getMethod("show", String.class, String.class);
showMethod2.invoke(p, "ab", "cd");
//调用私有方法
Method showMethod1 = clazz.getDeclaredMethod("show");
showMethod1.setAccessible(true);
showMethod1.invoke(p);
//调用静态方法
Method showMethod3 = clazz.getMethod("show", int.class);
showMethod3.invoke(null, 9);
}
}
数组的反射
具有相同维数和元素类型的数组属于同一个类型,即具有相同的字节码
代表数组的Class对象调用getSuperClass()方法返回的是Object字节码
非基本类型的一维数组,既可以当作Object类型使用,又可以当作Object[]类型使用,基本类型的一维数组只可以当作Object类型使用
import java.lang.reflect.Array;
/**
数组的反射应用
*/
class ArrayReflect
{
public static void main(String[] args)
{
int[] arr1 = new int[]{1, 2, 3};
String str = "abc";
printObject(arr1);
printObject(str);
}
public static void printObject(Object obj)
{
Class clazz = obj.getClass();
//如果是数组
if(clazz.isArray())
{
//获取数组长度,Array类代表数组类型
int len = Array.getLength(obj);
for(int i = 0; i < len; i++)
{
System.out.println(Array.get(obj, i));
}
}
else
{
System.out.println(obj);
}
}
}
---------------------- ASP.Net+Android+IOS开发</a>、 .Net培训、期待与您交流! ----------------------