• 反射


    使用反射经常要用到的类,位于java.lang.reflect包中。

    --Class类:代表一个类

    --Field类:代表类的成员变量

    --Method类:代表类的方法

    --Constructor类:代表类的构造方法

    --Array类:提供一个动态创建的数组,以及访问数组元素的静态方法。

     

    使用Method

    public class RefletTest

    {

        public static void main(String[] args) throws Exception

        {

           Class<?> classType = Class.forName("java.lang.String");

          

           //getDeclaredMethods获得对应类的所有方法,包括private

           Method[] methods = classType.getDeclaredMethods();

          

           for(Method method : methods)

           {

               System.out.println(method);

           }

        }

    }

     

    使用反射进行方法的调用 

    public class InvokeTester

    {

        public int add(int a,int b)

        {

           return a + b;

        }

       

        public void output(String msg)

        {

           System.out.println(msg);

        }

       

        public static void main(String[] args) throws Exception

        {

           //取得自定义类的类型

           Class<?> classType = InvokeTester.class;

          

           //创建自定义的一个实例

           Object invokeTester = classType.newInstance();

          

           //取得自定义类的一个方法

           Method addMethod = classType.getMethod("add", new Class[]{int.class, int.class });

          

           //调用自定义类的实例的方法

           Object result = addMethod.invoke(invokeTester, new Object[]{1, 2});

           

           System.out.println(result);

          

           Method outputMethod = classType.getMethod("output",new Class[]{String.class});

          

           outputMethod.invoke(invokeTester,new Object[]{"Hello"});

          

           System.out.println(Object.class);

        }

    }

     

     

     

    要使用反射,首先需要获得待处理类或对象所对应的Class对象。

     

    获取某个类或某个对象对应的Class对象的常用的3种方式:

    a.使用Class类的静态方法forName.Class.forName(“java.lang.String”);

    b.使用类的.class语法:String.class

    c.使用对象的getClass()方法:String s = “a”; Class<?> clazz = s.getClass();

    public class ClassTest

    {

        public static void main(String[] args)

        {

            Class<?> classType = Child.class;

     

           System.out.println(classType);

     

           classType = classType.getSuperclass();

     

           System.out.println(classType);

     

           classType = classType.getSuperclass();

     

           System.out.println(classType);

     

           classType = classType.getSuperclass();

     

           System.out.println(classType);

          

        }

    }

     

    class Parent

    {

     

    }

     

    class Child extends Parent

    {

     

    }

     

     

    Constructor类的使用

    若想调用类的不带参数的构造方法来生成对象,我们有两种方法:

    a.    先获得Class对象,然后通过该Class对象的newInstance()方法直接生成即可。

    Class<?> clazz = String.class;

    Object object = clazz.newInstance();

     

    b.    先获得Class对象,然后通过该对象获得对应的Constructor对象,再通过该Constructor对象的newInstance方法生成:

    Class<?> clazz = Customer.class;

    Constructor cons = clazz.getConstructor(new Class[]{});

    Object obj = cons.newsInstance(new Object[]{});

     

     

    若想调用类的带参数的构造方法,可以用如下方式:

    Class<?> clazz = Customer.class;

    Constructor cons = clazz.getConstructor(new Class[]{String.class,int.class});

    Object obj = cons.newsInstance(new Object[]{“jack”,23});

     

     

     

    public class Customer

    {

        private long Id;

        private String name;

        private int age;

       

        public Customer()

        {

          

        }

       

        public Customer(String name, int age)

        {

           this.name = name ;

           this.age = age;

        }

     

        public long getId()

        {

           return Id;

        }

     

        public void setId(long id)

        {

           Id = id;

        }

     

        public String getName()

        {

           return name;

        }

     

        public void setName(String name)

        {

           this.name = name;

        }

     

        public int getAge()

        {

           return age;

        }

     

        public void setAge(int age)

        {

           this.age = age;

        }

    }

     

    public class ConstructorTest

    {

        //这个方法用于实现对object对象的拷贝操作

        public Object copy (Object object) throws Exception

        {

           /*

           Class<?> classType = object.getClass();

          

           //可以用于各种构造函数

           Constructor cons = classType.getConstructor(new Class[]{String.class , int.class});

          

           Object obj = cons.newInstance(new Object[]{"Jack", 30});

          

           //以上两行相当于下面的一行,但是下面这种用法,只能用于无参的构造函数。

           //Object obj1 = classType.newInstance();

           System.out.println(obj);*/

          

           Class<?> classType = object.getClass();

           Object objCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});

          

           Field[] fields = classType.getDeclaredFields();

          

           for(Field field : fields)

           {

               String name = field.getName();

               String firstLetter = name.substring(0,1).toUpperCase();

              

               String getMethodName = "get" + firstLetter + name.substring(1);

               String setMethodName = "set" + firstLetter + name.substring(1);

              

               Method getMethod = classType.getMethod(getMethodName,new Class[]{});

               Method setMethod = classType.getMethod(setMethodName,new Class[]{field.getType()});

              

               Object value = getMethod.invoke(object, new Object[]{});

               setMethod.invoke(objCopy, new Object[]{value});

           }

          

           return objCopy;

        }

       

        public static void main(String[] args) throws Exception

        {

           Customer customer = new Customer("Jack",30);

           customer.setId(1L);

           ConstructorTest test = new ConstructorTest();

           Customer customer2 = (Customer)test.copy(customer);

          

           System.out.println(customer2.getId()+ "," + customer2.getName() + "," + customer2.getAge());

        }

    }

     

     

    使用反射创建数组

    public class ArrayTest2

    {

        public static void main(String[] args)

        {

           int[] dims = new int[]{5, 10, 15};

          

           Object array = Array.newInstance(Integer.TYPE, dims);

          

           Object arrObj = Array.get(array, 3);

          

           Class<?> classType = arrObj.getClass().getComponentType();

          

           System.out.println(classType);

          

           arrObj = Array.get(arrObj , 5);

          

           Array.setInt(arrObj, 10, 35);

          

           int[][][] arrCast = (int[][][])array;

          

           System.out.println(arrCast[3][5][10]);

        }

    }

     

     

    public class ArrayTest

    {

        public static void main(String[] args) throws Exception

        {

           Class<?> classType = Class.forName("java.lang.String");

          

           Object array = Array.newInstance(classType, 10);

          

           Array.set(array, 5, "Jack");

          

           Object val = Array.get(array, 5);

          

           System.out.println(val);

        }

    }

     

     

    使用反射调用类里的私有方法:

    public class PrivateTest

    {

        public static void main(String[] args) throws Exception

        {

           Person p = new Person();

          

           Class<?> classType = p.getClass();

          

           Method method = classType.getDeclaredMethod("sayHello" ,new Class[]{String.class});

          

           method.setAccessible(true);//压制java的类型检查

          

           Object val = method.invoke(p, new Object[]{"Alens"});

          

           System.out.println(val);

        }

    }

     

    class Person

    {

        private String sayHello(String name)

        {

           return "Hello," + name;

        }

    }

     

    public class PrivateTest2

    {

        public static void main(String[] args) throws Exception

        {

           People p = new People();

          

           Class<?> classType = p.getClass();

          

           Field field = classType.getDeclaredField("name");

          

           field.setAccessible(true);

          

           field.set(p, "Lisi");

          

           Method method = classType.getDeclaredMethod("getName", new Class[]{});

          

           Object name = method.invoke(p, new Object[]{});

          

           System.out.println(name);

        }

    }

     

    class People

    {

        private String name = "ZhangSan";

       

        public String getName()

        {

           return this.name;

        }

    }

     

     

    注意:Integer.Type返回的是int,Integer.class返回的是Class对象。

     

  • 相关阅读:
    SQL SERVER事务处理
    设计模式之简单工厂模式(静态工厂方法)
    设计模式之工厂方法模式
    为什么静态成员变量要通过类外初始化赋值?
    c++中可以对类中私有成员中的静态变量初始化吗?
    C++中的虚函数(virtual function)
    C++ 基础学习笔记(2)函数(测试题)
    c++中子对象的初始化可在复合类的构造函数的函数体内进行吗?还是子对象的初始化只能在初始化列表中进行?
    C++学习笔记(五)虚函数表解析(转)
    看过的书籍(转)
  • 原文地址:https://www.cnblogs.com/zfc2201/p/2143696.html
Copyright © 2020-2023  润新知