Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。. 这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。. 反射被视为动态语言的关键
反射的使用反射第一步:获取要 *** 作的类的类对象 类对象:Class类 JVM(java虚拟机)每当加载一个类时(读取要 *** 作的类的字节码文件),就会实例化一个Class的实例来表示刚加载的这个类。在JVM内部每个被加载的类都有且只有一个Class的实例与之对应。通过这个Class实例我们可以在程序运行期间了解其表示的类的一切信息(类名,有哪些方法,那些属性,那些构造器等)并在运行期间进行 *** 作 获取类对象的方式有三种: 1:类名.class Class cls = String.class; Class cls = int.class;(基本类型只有这一种方式获取类对象) 2:Class.forName(String className) 参数为要 *** 作的类的完全限定名:包名.类名 Class cls = Class.forName("java.lang.String"); 3:ClassLoader类加载形式获取类对象 */ String name = cls.getName();//获取类名(完全限定名) System.out.println(name); name = cls.getSimpleName();//仅获取类名 System.out.println(name); //列如: Scanner scanner=new Scanner(System.in); System.out.println("请输入一个类名:"); String className=scanner.nextLine(); Class cls=Class.forName(className); String name = cls.getName();//获取类名(完全限定名) System.out.println(name); name = cls.getSimpleName();//仅获取类名 System.out.println(name); Method[] methods=cls.getMethods(); for (Method method:methods){ System.out.println(method.getName()); }使用反射机制实例化对象
1.加载类对象 调用的包名.类名 Class cls=Class.forName("reflect.Person"); //2.Class提供了一个方法:newInstance()方法,可以调用其表示的类的公开的无参构造进行实例化 Object o=cls.newInstance(); //列如: Scanner scanner=new Scanner(System.in); while (true){ System.out.println("请输入一个类名:"); String className=scanner.nextLine(); Class cls=Class.forName(className); Object o=cls.newInstance(); System.out.println(o); }获取类的公开方法:
Method[] methods=cls.getMethods(); for (Method method:methods){ System.out.println(method.getName()); }获取构造器:
Class cls=Class.forName("reflect.Person"); //Constructor类的每一个实例用于表示一个构造方法 // Constructor c=cls.getConstructor();//不传参获取的就是无参构造器 Constructor c=cls.getConstructor(String.class);//Person(String name) Object o=c.newInstance("王五");//new Person("王五") System.out.println(o); Constructor cs=cls.getConstructor(String.class,int.class); Object oc=cs.newInstance("132131w",126); System.out.println(oc);调用方法:
Scanner scanner=new Scanner(System.in); System.out.println("请输入类名:"); String className=scanner.nextLine(); System.out.println("请输入方法名:"); String methodName=scanner.nextLine(); //1.加载类对象 Class cls=Class.forName(className); //2.实例化 Object obj=cls.newInstance();//使用默认构造器实例化对象,Person p=new Person //根据类对象获取要 *** 作的方法对象 Method method=cls.getMethod(methodName); //调用方法 method.invoke(obj);//p.sayGoodBye //调用一个参数的方法 Class cls=Class.forName("reflect.Person"); Object obj=cls.newInstance(); Method method=cls.getMethod("say",String.class); method.invoke(obj,"大家好~~~"); //调用两个的参数方法 Method method1=cls.getMethod("say", String.class, int.class); method1.invoke(obj,"今天周末",2);调用私有方法(一般不要使用):
Class cls=Class.forName("reflect.Person"); Object obj=cls.newInstance(); Method method=cls.getDeclaredMethod("dosome"); if (method.getModifiers()== Modifier.PRIVATE){//判断该方法是否为private方法 method.setAccessible(true);//强行打开访问 } method.invoke(obj);//p.dosome()在反射机制中判定是否有被某个注解标注的类
public static void main(String[] args) throws URISyntaxException, ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException { File dir=new File( ReflectDemo7.class.getResource(".").toURI() ); File[] subs=dir.listFiles(f->f.getName().endsWith(".class")); for (File file:subs) { String fileName=file.getName(); String className=fileName.substring(0,fileName.indexOf(".")); Class cls=Class.forName("reflect."+className); //判断当前类是否被注解@AutoRunClass标注过 // boolean tf=cls.isAnnotationPresent(AutoRunClass.class); // System.out.println(className+"是否被标注"+tf); if (cls.isAnnotationPresent(AutoRunClass.class)){ Object o=cls.newInstance(); Method[] methods=cls.getDeclaredMethods(); for (Method method:methods) { if (method.isAnnotationPresent(AutoRun.class)){ AutoRun ar=method.getAnnotation(AutoRun.class); int value=ar.value(); System.out.println("@AutoRun("+value+")"); System.out.println("自动调用"+cls.getName()+"的方法"+method.getName()+"()"); method.setAccessible(true); method.invoke(o); } } } } }调用含有s的无参方法
public class Text { public static void main(String[] args) throws URISyntaxException { File file=new File(Text.class.getResource(".").toURI()); System.out.println(file.getAbsolutePath()); File[] subs=file.listFiles(f->f.getName().endsWith(".class")); for (File sub:subs) { String fielName=sub.getName(); String className=fielName.substring(0,fielName.indexOf(".")); System.out.println("类名"+className); try { Class cls = Class.forName("reflect."+className); Object obj=cls.newInstance(); Method[] methods=cls.getDeclaredMethods(); for (Method method:methods) { if (method.getModifiers()== Modifier.PUBLIC && method.getParameterCount()==0){ System.out.println("自动执行"+cls.getName()+"的方法"+method.getName()+"()"); method.invoke(obj); } } } catch (Exception e) { e.printStackTrace(); } } } }调用别的类的main方法:
//定位包: map包 File dir=new File( Text2.class.getClassLoader().getResource("./map").toURI() ); System.out.println(dir.getAbsolutePath()); File[] subs=dir.listFiles(f->f.getName().endsWith(".class")); for (File sub:subs) { String fileName=sub.getName(); String className=fileName.substring(0,fileName.indexOf(".")); try { Class cls = Class.forName("map."+className); System.out.println("准备执行"+cls.getName()+"的main方法"); Method method=cls.getMethod("main",String[].class); method.invoke(null,(Object)new String[]{}); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { System.out.println("没有main方法"); } catch (Exception e) { e.printStackTrace(); } } } }调用在同一包含有s的无参方法:
//定位包: map包 File dir=new File( Text2.class.getClassLoader().getResource("./map").toURI() ); System.out.println(dir.getAbsolutePath()); File[] subs=dir.listFiles(f->f.getName().endsWith(".class")); for (File sub:subs) { String fileName=sub.getName(); String className=fileName.substring(0,fileName.indexOf(".")); try { Class cls = Class.forName("map."+className); System.out.println("准备执行"+cls.getName()+"的main方法"); Method method=cls.getMethod("main",String[].class); method.invoke(null,(Object)new String[]{}); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { System.out.println("没有main方法"); } catch (Exception e) { e.printStackTrace(); } } } }注解:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface AutoRunClass { int value() default 1; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)