您的位置:首页 > 职场人生

黑马程序员 java 反射详解

2012-02-28 23:27 459 查看
(1)、反射的基础知识

J***A反射机制可以说是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。

反射的基石: Class 字节码

得到这个类的字节码的实例对象有3种

类名.class 如,System.class;

对象.class 如p1.getClass();

Class.forName("java.lang.String");

package cn.oyb.fanshe;
public class fansheTest {
	public static void main(String[] args) throws Exception {
		String str1 = "abc";
		Class cls1 = str1.getClass();
		Class cls2 = String.class;
		Class cls3 = Class.forName("java.lang.String");
		System.out.println(cls1 == cls2); //true
		System.out.println(cls2 == cls3); //true

		System.out.println(cls1.isPrimitive());//是否是一个基本类型的字节码 //flase  
		System.out.println(int.class.isPrimitive()); //true  
		System.out.println(int.class == Integer.class); //false  
		System.out.println(int.class == Integer.TYPE); //基本类型可以写成这样 true  
		System.out.println(int[].class.isPrimitive()); //false  
		System.out.println(int[].class.isArray()); //数组的Class实例对象 true  
	}  
}


(2)、反射加强知识

反射就是把Java类中的各种成分映射成相应的java类。

可以获取其中的变量属性(Field),方法(Method),构造方法(Constructor),修饰符(Modifier),包(Package)等信息。

1,得到某个类所有的构造方法

Constructor[] constructor = Class.forName("java.lang.Sting").getConstructor();

2,得到类中某一个构造方法 //获得方法时要用到类型

Constructor con1 = Class.forName("java.lang.String").getConstructor(String.class);

3,创造实例对象 //要用到上面

String str = (String)con1.newInstance(new String("abc"));

//这里该方法得到构造方法,然后用该构造方法创造实例对象。

Constructor constructor1 = String.class.getConstructor(String.class);

String str = (String) constructor1.newInstance(new String("abc"));

System.out.println(str);

Field类---成员变量属性的反射

package cn.oyb.fanshe;

public class ReflectTest {
    private int x;  
    public int y;  
    public String str1 = "ball";  
    public String str2 = "basketball";  
    public String str3 = "itcast";  
    public ReflectTest(int x, int y) {  
        this.x = x;  
        this.y = y;  
    }  
    public String toString() {  
        return str1+":"+str2+":"+str3;  
    } 
}


//获得其值的方法

ReflectTest pt1 = new ReflectTest(2,5);
Field fieldY = pt1.getClass().getField("y"); //y是public 
System.out.println(fieldY.get(pt1)); 
Field fieldX = pt1.getClass().getDeclaredField("x");//x是private私有的 
fieldX.setAccessible(true); //需要设置暴力反射 
System.out.println(fieldX.get(pt1));



//把对象上所有的String成员变量中的"b"换成"a"//main StringReplace(pt1)
private static void StringReplace(Object obj) throws Exception {  
        Field[] fields = obj.getClass().getFields();  
        for(Field field : fields){  
            if(field.getType() == String.class){  
                String  oldValue = (String) field.get(obj);  
                String  newValue = oldValue.replace("b", "a");  
                field.set(obj, newValue);  
            }  
        }  
    }


Method类 ---代表某个类上的一个成员方法

----得到类中的某一个方法

Method method = Class.forName("java.lang.String").getMethod("方法名称",int.class); //int.class为该方法参数类型

---调用方法

method.invoke(对象,参数); //例如method.invoke(pt1,23);

//如果传递给Method对象的invoke()方法的一个参数为null,,,说明该Method对象对应的是一个静态方法

用反射方式执行某个类中的main方法

在类中再增加一个类

class Test{

public static void main(String[] args) {

for(String arg :args)

System.out.println(arg);

}

}

//用反射调用

String startmain = args[0]; //main中传入上面类名

Method mainMethod = Class.forName(startmain).getMethod("main", String[].class);



------------------------反射的基本操作实例-------------------------------------------------

Person.java

public class Person {  
  
    private String name;  
    private int age;  
    private static int total;  
      
    private Person() {  
        super();  
        total++;  
    }  
  
    private Person(String name, int age) {  
        super();  
        this.name = name;  
        this.age = age;  
    }  
  
    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 static int getTotal() {  
        return total;  
    }  
  
    public static void setTotal(int total) {  
        Person.total = total;  
    }  
  
    @Override  
    public String toString() {  
        return "name:"+name+",age:"+age;  
    }         
}

测试类

public class TestReflection {  
    public static void main(String[] args) {  
        try {  
            Class<?> c = Person.class;  
            //解析属性  
            Field[] fs = c.getDeclaredFields();  
            for(Field f : fs){  
                System.out.println("-----------------------");  
                System.out.println("属性:"+f.toString());  
                System.out.println("/t数据类型:"+f.getType());  
                System.out.println("/t属性名称:"+f.getName());  
                int mod = f.getModifiers(); //返回这个字段的修饰符  
                System.out.println("/t属性修饰符:"+ Modifier.toString(mod));  
            }  
            //解析方法  
            Method[] ms = c.getDeclaredMethods();  
            for(Method m :ms){  
                System.out.println("-----------------------");  
                System.out.println("方法:"+m.toString());  
                System.out.println("/t方法名:"+m.getName());  
                int mod = m.getModifiers(); //返回这个字段的修饰符  
                System.out.println("/t方法修饰符:"+ Modifier.toString(mod));  
                System.out.print("/t方法参数列表:");  
                Class pts[] = m.getParameterTypes(); //参数列表  
                for(int i=0;i<pts.length;i++){  
                    Class class1 = pts[i];  
                    if(i!=0)  
                        System.out.print(",");     //这里标逗号,值得借鉴  
                    System.out.print(class1);  
                }  
                System.out.println();  
                System.out.println("/t返回值类型:"+m.getReturnType());// 方法的返回值类型  
            }     
            System.out.println("-构造方法信息-----------------------------------");  
                //解析构造方法  
                Constructor[] cs = c.getConstructors();  
                for(Constructor con :cs){  
                    System.out.println("-----------------------");  
                    System.out.println("构造方法:"+con.toString());  
                    System.out.println("/t构造方法名:"+con.getName());  
                    int mod = con.getModifiers();  
                    System.out.println("/t方法修饰符:"+ Modifier.toString(mod));  
                    System.out.println("/t方法参数列表:");  
                    Class pts[] = con.getParameterTypes(); //参数列表  
                    for(int i=0;i<pts.length;i++){  
                        Class class1 = pts[i];  
                        if(i!=0)  
                            System.out.print(",");     //这里标逗号,值得借鉴  
                        System.out.print(class1);  
                    }  
                    System.out.println();  
                }  
                System.out.println("------------------------------------");  
                //解析当前类型的父类  
                Class getSuper = c.getSuperclass();  
                System.out.println("当前父类:"+getSuper.toString());  
                System.out.println("----------------");  
                //当前实现的接口  
                Class[] interfaces = c.getInterfaces();  
                System.out.println("当前实现的所有接口:");  
                for(Class class1 : interfaces){  
                    System.out.println(class1.toString()+"/t");  
                }  
                System.out.println("/n------------------------------------");  
                //当前所在包信息  
                Package p =c.getPackage();  
                System.out.println("当前所在包:"+c.toString());  
        } catch (ClassNotFoundException e) {  
            e.printStackTrace();  
        }  
    }  
  
}

---------------------------2例---------------------------------------------------------------

User.java

public class User {  
    public String name;  
    public int age;  
    public static int total=10;  
/*  public User() { 
        super(); 
        total++; 
    }*/  
    public User(String name, int age) {  
        super();  
        this.name = name;  
        this.age = age;  
        total++;  
    }  
      
    public void setAll(String name,int age){  
        this.name = name;  
        this.age = age;  
    }  
    public static void showTotal(){  
        System.out.println("int total showTotal,total="+total);  
    }  
    public String toString(){  
        return "用户名:"+name+",年龄:"+age;  
    }  
}

测试

public class TestRefUer {  
  
    public static void main(String[] args) throws Exception {  
        User u1 = new User("dd", 33);  
        TestRefUer tf = new TestRefUer();  
          
        System.out.println("-------------------------------");  
        tf.mdf(u1, "name", "刷个");  
        tf.mdf(u1, "age", 13);  
        System.out.println(u1);  
        System.out.println("-------------------------------");  
        tf.mdf1("Reflect.User", "total", 44);  
        System.out.println("-------------------------------");  
    //  Class[] argtype = new Class[]{String.class,int.class};  
        Class[] argtype = {String.class,int.class};           //同上...  
        Object[] argss = new Object[]{"王武",88};  
        tf.mdf2(u1, "setAll", argtype, argss);  
        System.out.println(u1);  
        System.out.println("-------------------------------");  
        tf.mdf4("Reflect.User", "showTotal", new Class[0], new Object[0]);  
          
    }  
    //直接操作对象属性  
    public void mdf(Object o,String fieldName,Object newValue) throws Exception{  
        Class c = o.getClass();  
        Field f = c.getField(fieldName);  
        Object field = f.get(o);  
        System.out.println("修改前:"+fieldName+"="+field);  
        f.set(o, newValue);  
        System.out.println("修改后:"+fieldName+"="+f.get(o));  
    }  
    //直接操作类属性  
    public void mdf1(String o,String fieldName,Object newValue) throws Exception{  
        Class c = Class.forName(o);  
        Field f = c.getField(fieldName);  
        Object field = f.get(o);  
        System.out.println("修改前:"+fieldName+"="+field);  
        f.set(c, newValue);    //这里操作的是class对象  
        System.out.println("修改后:"+fieldName+"="+f.get(c));  
    }  
    //调用对象成员,赋值  
    public void mdf2(Object obj,String methodName,Class[] argType,Object[] args) throws Exception{  
        Class c = obj.getClass();  
        Method m = c.getMethod(methodName, argType);  
        Object result = m.invoke(obj, args);  
        //System.out.println(result);  
    }  
    //调用类成员方法  
    public void mdf4(String obj,String methodName,Class[] argType,Object[] args) throws Exception{  
        Class c = Class.forName(obj);  
        Method m = c.getMethod(methodName, argType);  
        Object result = m.invoke(null, args);   
        //System.out.println(result);  
    }  
  
}

----------------------------------调用构造方法----------------------------------------------

import java.lang.reflect.Constructor;  
  
public class TestRefUser2 {  
      
    public static void main(String[] args) {  
        Class c ;  
        try {  
            //调用有参构造方法  
            c = .User.class;
            Class[] argTypes = {String.class,int.class};  //此处为User类的有参构造方法参数类型  
            Constructor cons = c.getConstructor(argTypes);  
            Object obj = cons.newInstance("中国",5333);  
            System.out.println(obj);  
            //调用无参  
            cons =c.getConstructor();  
            //等同cons = c.getConstructor(new Class[0]);  
            //cons = c.getConstructor(null);  
            obj = cons.newInstance();  
            System.out.println(obj);  
              
            //调用参构造方法2  
            obj = c.newInstance();  
            System.out.println(obj+"dd");  
        } catch (Exception e) {  
        }  
    }  
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: