zoukankan      html  css  js  c++  java
  • Java中的反射[转载]

    转自:https://blog.csdn.net/sinat_38259539/article/details/71799078#commentBox

    1.什么是反射?

     反射是通过一个类可以知道其中所含的属性和方法,并且对于一个对象可以调用它的任意属性和方法;

     这种动态获取信息以及动态调用对象的方法就是JAVA语言的反射机制。

    2. 反射就是把JAVA类中的各种成分映射成一个对象

    比如类中有成员变量,方法,构造方法等信息,利用反射技术对一个类进行解剖,把各个组成部分映射成为一个对象

    //因为每个类定义是只有一个的,对象可以实例化很多个,以前的理解还是太粗浅了。

    3.重要的Class类

    获取Class对象的三种方法:

    package fanshe;
    /**
     * 获取Class对象的三种方式
     * 1 Object ——> getClass();
     * 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
     * 3 通过Class类的静态方法:forName(String  className)(常用)
     *
     */
    public class Fanshe {
        public static void main(String[] args) {
            //第一种方式获取Class对象  
            Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
            Class stuClass = stu1.getClass();//获取Class对象
            System.out.println(stuClass.getName());
            
            //第二种方式获取Class对象
            Class stuClass2 = Student.class;
            System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
            
            //第三种方式获取Class对象
            try {
                Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
                System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            
        }
    }

    1)通过对象的getClass()函数获取

    2)通过对象的class属性获取(任何数据类型,包括基本数据类型都有一个静态的class属性)

    3)通过Class类的静态方法forName("报名.类名");

    在运行期间,一个类只有一个class对象产生。

    第三种方法是常用的,可以通过一个字符串来创建对象。

    并且给出了一些例子,

    例1:

    可以反射数据成员、方法、构造函数、并且可以反射main方法:

    Student类:

    package fanshe.main;
     
    public class Student {
     
        public static void main(String[] args) {//定义了一个main方法。
            System.out.println("main方法执行了。。。");
        }
    }

    Main类:

    package fanshe.main;
     
    import java.lang.reflect.Method;
     
    /**
     * 获取Student类的main方法、不要与当前的main方法搞混了
     */
    public class Main {
        
        public static void main(String[] args) {
            try {
                //1、获取Student对象的字节码
                Class clazz = Class.forName("fanshe.main.Student");
                
                //2、获取main方法
                 Method methodMain = clazz.getMethod("main", String[].class);//第一个参数:方法名称,第二个参数:方法形参的类型,
                //3、调用main方法
                // methodMain.invoke(null, new String[]{"a","b","c"});
                 //第一个参数,对象类型,因为方法是static静态的,所以为null可以,第二个参数是String数组,这里要注意在jdk1.4时是数组,jdk1.5之后是可变参数
                 //这里拆的时候将  new String[]{"a","b","c"} 拆成3个对象。。。所以需要将它强转。
                 methodMain.invoke(null, (Object)new String[]{"a","b","c"});//方式一
                // methodMain.invoke(null, new Object[]{new String[]{"a","b","c"}});//方式二
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            
            
        }
    }

    例2:

    可以通过配置文件来定义

    public class Student {
        public void show(){
            System.out.println("is show()");
        }
    }

    配置文件pro.txt

    className = cn.fanshe.Student
    methodName = show

    测试类:

    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.lang.reflect.Method;
    import java.util.Properties;
     
    /*
     * 我们利用反射和配置文件,可以使:应用程序更新时,对源码无需进行任何修改
     * 我们只需要将新类发送给客户端,并修改配置文件即可
     */
    public class Demo {
        public static void main(String[] args) throws Exception {
            //通过反射获取Class对象
            Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student"
            //2获取show()方法
            Method m = stuClass.getMethod(getValue("methodName"));//show
            //3.调用show()方法
            m.invoke(stuClass.getConstructor().newInstance());
            
        }
        
        //此方法接收一个key,在配置文件中获取相应的value
        public static String getValue(String key) throws IOException{
            Properties pro = new Properties();//获取配置文件的对象
            FileReader in = new FileReader("pro.txt");//获取输入流
            pro.load(in);//将流加载到配置文件对象中
            in.close();
            return pro.getProperty(key);//返回根据key获取的value值
        }
    }
  • 相关阅读:
    Hive和HBase的区别
    HBase面试问题
    HBase的rowkey的设计原则
    一、spark 数据类型(Data Types)
    Phaser显示对象(文字)
    Phaser中的组对象group
    Phaser中的动画
    phaser.js 显示对象笔记
    MD5之C#密码加密备忘录
    学了点小小的技巧,也有一点点问题,怎么解决呢?
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/9624271.html
Copyright © 2011-2022 走看看