入门java的第n天---反射

入门java的第n天---反射,第1张

入门java的第n天---反射 反射与注解: 什么是反射?

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;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5684266.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存