Java反射

Class类的使用

package com.zyz;

/**
 * Created by zyz on 2016-9-22.
 */
public class ClassDemo1 {
    public static void main(String[] args){
        Foo foo1=new Foo();
        //第1种表示法---Foo类也是一个对象,任何一个类都会有一个静态的成员变量class
        Class c1=Foo.class;
        // 第2种表示法
        Class c2=foo1.getClass();
        //c1,c2表示Foo类的类类型(class type)
//        万事万物皆对象
//        类也是对象,是Class类的实例对象
//        这个对象我们称之为该类的类类型
        System.out.println(c1==c2);//true,c1,c2都代表了Foo类的类类型,一个类只能是Class类的一个实例对象
        //第3种表示法
        Class c3=null;
        try {
            c3 = Class.forName("com.zyz.Foo");
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
        System.out.println(c2==c3);//true
        //我们可以通过类的类类型创建该类的实例对象,-->通过c1或c2或c3创建Foo类的实例对象
        try {
            Foo foo=(Foo)c1.newInstance();//需要有无参数的构造方法
            foo.print();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
class Foo{
    void print(){
        System.out.println("foo");
    }
}
//--------------静态加载------------------
class Office{
    public static void main(String[] args) {
        if("Word".equals(args[0])){
            Word word=new Word();
            //new 创建对象是静态加载类,在编译时刻就要加载所有可能用到的类,即无论是传的参数是"Word"还是"Excel",Word和Excel的类型必须创建并编译成Class文件。
            word.start();
        }
        if("Excel".equals(args[0])){
            Excel excel=new Excel();
            excel.start();
        }
    }
}


//--------------------动态加载,即运行时加载----------------
//定义一个接口
interface OfficeAble {
    public void start();
}

//定义Word类实现接口
class Word implements OfficeAble {
    public  void start(){
        System.out.println("word...starts...");
    }
}


//定义Excel类实现接口
class Excel implements OfficeAble {
    public  void start(){
        System.out.println("excel...starts...");
    }
}


//改进的Office类
class OfficeBetter{
    public static void main(String[] args) {
        try{
            Class c=Class.forName(args[0]);//得到传入的参数得到该类的类类型
            
            OfficeAble oa=(OfficeAble)c.newInstance();//创建该类的对象
            oa.start();//调用该类实现的方法

        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
/**
 * Created by Administrator on 16-9-22.
 */
public class ClassDemo2 {
    public static void main(String[] args){
        Class c1=int.class;
        Class c2=String.class;
        Class c3=double.class;
        Class c4=Double.class;
        Class c5=void.class;
        System.out.println(c1.getName());//int
        System.out.println(c2.getName());//java.lang.String
        System.out.println(c2.getSimpleName());//String
        System.out.println(c3.getName());//double
        System.out.println(c4.getName());//java.lang.Double
        System.out.println(c5.getName());//void

    }
}
package com.zyz;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Created by Administrator on 16-9-22.
 */
public class ClassUtil {
    /**
     * 打印类的方法信息
     * @param object 该对象所属类的信息
     * */
    public static void printMethodMessage(Object object){
        //首先要获取类的类类型
        Class c=object.getClass();//传递的是哪个子类的对象
        System.out.println("类的名称为:"+c.getName());
        /*
        Method类,是方法对象
        一个成员方法就是一个Method对象
        getMethods方法是获取所有public方法,包括从父类继承过来的方法
        getDeclaredMethods获取的是所有该类自己声明的方法,不问访问权限
        * */
        Method[] ms=c.getMethods();
        for(Method m:ms){
            /*得到方法的返回值类类型*/
            Class returnType=m.getReturnType();
            System.out.print(returnType.getName()+" ");//返回值类型名称
            System.out.print(m.getName()+"(");//方法名称
            //获取参数类型-->得到的是参数列表的类类型
            Class[] paramTypes=m.getParameterTypes();
            for(Class c1:paramTypes){
                System.out.print(c1.getName()+",");
            }
            System.out.println(")");
        }
    }

    /**
     * 打印成员变量的信息
     * @param obj
     */
    public static void printFieldMessage(Object obj) {
        /**
         * 成员变量也是对象
         * java.lang.reflect.Field
         * Field类封装了关于成员变量的一些操作
         * getFields()是获取所有public成员变量的信息
         * getDeclaredFields()是获取该类自己声明的成员变量的信息
         */
        Class c=obj.getClass();
        Field[] fs=c.getDeclaredFields();
        for(Field field:fs){
            Class fieldType=field.getType();//得到成员变量的类类型,如int.class
            String typeName=fieldType.getName();//得到类型名
            String fieldName=field.getName();//得到变量名
            System.out.println(typeName+" "+fieldName);
        }
    }

    /**
     * 打印构造函数的信息
     */
    public static void printConMessage(Object obj){
        Class c=obj.getClass();
        /*
        构造函数也是对象
        java.lang.Contructor
        getConstuctors获取所有的public构造函数
        getDeclaredConstructors得到所有的构造函数
         */
        Constructor[] cs=c.getDeclaredConstructors();
        for(Constructor constructor:cs){
            System.out.print(constructor.getName()+"(");
            //获取构造函数参数列表--->得到的是参数列表的类类型
            Class[] paramTypes=constructor.getParameterTypes();
            for(Class c1:paramTypes){
                System.out.print(c1.getName()+",");
            }
            System.out.println(")");


        }
    }
}
package com.zyz;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * Created by Administrator on 16-9-25.
 */
public class MethodDemo4 {
    public static void main(String[] args){
        ArrayList list=new ArrayList();
        ArrayList<String> list1=new ArrayList<String>();
        list.add(1);
        list1.add("hello");
//        list1.add(20);不能通过编译阶段
        Class c1=list.getClass();
        Class c2=list1.getClass();
        System.out.println(c1==c2);//true
        //反射的操作都是编译之后的操作
        //c1==c2结果返回true说明编译之后的集合的泛型是去泛型化的。
        //java中集合的泛型,是防止错误输入,只在编译阶段有效,绕过编译就无效了。
        //我们可以通过方法的反射来操作,绕过编译
        Method m= null;
        try {
            m = c2.getMethod("add",Object.class);
            m.invoke(list1,20);//绕过编译操作就绕过了泛型
            System.out.println(list1.size());//2
            System.out.println(list1);//[hello,20]
//            for(String str:list1){
//                System.out.println(str);
//            }现在就不能这样遍历了
            for(Object obj:list1){
                System.out.println(obj);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }

}
原文地址:https://www.cnblogs.com/beast-king/p/5896494.html