反射

使用反射经常要用到的类,位于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对象。

 

原文地址:https://www.cnblogs.com/zfc2201/p/2143696.html