一、基本反射技术
1.1
getClass():根据一个对象获得它的类
public class Test4 { public static void main(String[] args) { Role r1=new Role(); Class<? extends Role> c1=r1.getClass(); System.out.println(c1);//打印:class euler1.Role System.out.println(c1.getName());//euler1.Role System.out.println(c1.getSimpleName());//Role System.out.println(c1.getTypeName());//euler1.Role System.out.println(Arrays.toString(c1.getConstructors()));//[public euler1.Role()] } }
Class.forName():根据类的全限定名获得它的类
public class Test4 { public static void main(String[] args) { String s1="euler1.Role";//只能打全限定名 Class<?> c2=null; try { c2 = Class.forName(s1);
System.out.println(c2);//class euler1.Role System.out.println(c2.getSimpleName());//Role } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
Type属性:
基本类型都有type属性,可以得到这个基本类型的类型,比如
Class c1 = Boolean.TYPE; Class c2 = Byte.TYPE; Class c3 = Float.TYPE; Class c4 = Double.TYPE;
System.out.println(c1);//bolean
二、获取类的成员
当类中方法定义为私有的时候我们能调用?不能!当变量是私有的时候我们能获取吗?不能!但是反射可以,比如源码中有你需要用到的方法,但是那个方法是私有的,这个时候你就可以通过反射去执行这个私有方法,并且获取私有变量。
获取类的构造函数
获取类的所有构造方法
public static void main(String[] args) { Test test = new Test(); Class<? extends Test> c4 = test.getClass(); Constructor[] constructors ; Constructor[] constructors1 ; constructors = c4.getDeclaredConstructors();//getDeclaredConstructors()返回类的所有构造方法 constructors1 = c4.getConstructors();//getConstructors()返回类的所有public构造方法 System.out.println(Arrays.toString(constructors)); System.out.println(Arrays.toString(constructors1)); for(int i=0;i<constructors.length;i++) { //getModifiers可以得到构造方法的类型:private,public等等 System.out.print(Modifier.toString(constructors[i].getModifiers()) + "参数:"); //getParameterTypes可以得到构造方法的所有参数的类型,返回的是一个Class数组:比如返回int,String类型等等 Class[] parametertypes = constructors[i].getParameterTypes(); for(int j=0;j<parametertypes.length;j++) { System.out.print(parametertypes[j].getName() + " "); } System.out.println(""); } }
获取类中特定的构造方法
1)获取无参构造方法
public class Test5 { public static void main(String[] args) { Test test = new Test(); Class<? extends Test> c4 = test.getClass(); Constructor constructors ; try { //获取无参构造方法直接不传参数 constructors = c4.getDeclaredConstructor();//少个s就是返回的是一个Class对象而不是一个Class数组 System.out.print(Modifier.toString(constructors.getModifiers())); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
2)获取类中特定的构造方法
public static void main(String[] args) { Test test = new Test(); Class<? extends Test> c4 = test.getClass(); Class[] p={int.class,String.class}; Constructor constructors ; try { //获取特定构造方法,传一个指示参数个数及类型的class对象或数组 constructors = c4.getDeclaredConstructor(p);//少个s就是返回的是一个Class对象而不是一个Class数组 System.out.print(Modifier.toString(constructors.getModifiers())+" "); Class[] parametertypes = constructors.getParameterTypes(); for (int j = 0; j < parametertypes.length; j++) { System.out.print(parametertypes[j].getName() + " "); } } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
调用public构造方法
Class[] p = {int.class,String.class}; constructors = c4.getDeclaredConstructor(p); //传递参数进去 constructors.newInstance(24,"HuangLinqing");
调用私有构造方法
Class[] p = {String.class}; constructors = c4.getDeclaredConstructor(p); constructors.setAccessible(true); constructors.newInstance("HuangLinqing");
调用类的私有方法
我们知道如果我们要正常的调用类的方法都是通过类.方法调用,所以我们调用私有方法也需要得到类的实例,而我们上面newInstace已经得到了类的实例,这样就好办了。
Class[] p4 = {String.class};
//首先通过 getDeclaredMethod方法获取到这个私有方法,第一个参数是方法名,第二个参数是参数类型 Method method = c4.getDeclaredMethod("welcome",p4); method.setAccessible(true);
// 然后通过invoke方法执行,invoke需要两个参数一个是类的实例,一个是方法参数 Object arg1s[] = {"欢迎关注代码男人技术公众号"}; method.invoke(test,arg1s);
获取类的私有字段并修改值
看到这里你可能会说,有了set方法,什么私有不私有,test.set不就可以了,但是这里要注意我们是没有办法得到这个类的实例的,要不然都可以得到实例就没有反射一说了。我们在通过反射得到类的实例之后先获取字段:
Test test1=null; try { test1=(Test)Class.forName("euler1.Test").newInstance(); try {
//先获取字段 Field field=c4.getDeclaredField("name"); field.setAccessible(true);
//通过对象实例设置值 field.set(test1,"代码男人");
//获取值 System.out.println(field.get(test1).toString()); } catch (NoSuchFieldException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }
获取类的所有方法
构造方法,set,get方法,继承来的方法等等所有的方法
public class Test5 { public static void main(String[] args) { try { Class c1=Class.forName("euler1.Test");
//获取这个类的所有方法 Method[] methods = c1.getMethods(); System.out.println(Arrays.toString(methods)); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
--