Java 反射机制- reflect

1、反射机制是什么    

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意

一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方

法的功能称为java语言的反射机制。

反射其实就是实例化得到对象


2、反射机制能做什么

反射机制主要提供了以下功能

在运行时判断任意一个对象所属的类;

在运行时构造任意一个类的对象;

在运行时判断任意一个类所具有的成员变量和方法;

在运行时调用任意一个对象的方法;

生成动态代理。


下面是源码:


package Test;


import java.io.File;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.ArrayList;


import org.junit.Test;


import com.zking.entity.Person;


public class Testreflect implements Serializable {
/**
*  reflect  反射       2017/2/18
* @throws Exception
*/
   private String pname = null;
       @Test
            public void reflect() throws Exception{
        //1、通过一个对象获得完整的包名和类名
        /*Testreflect  testreflect=new Testreflect();
        System.out.println("Testreflect权限定名:"+testreflect.getClass().getName());*/
        //Testreflect权限定名:Test.Testreflect
       
       
       
        //2、实例化Class类对象
        /*Class<?> class1=null;
        Class<?> class2=null;
        Class<?> class3=null;*/
        // 一般采用这种形式
        /*class1=Class.forName("Test.Testreflect");
        class2=new Testreflect().getClass();
        class3=Testreflect.class;
        System.out.println("类名称:"+class1.getName());
        System.out.println("类名称:"+class2.getName());
        System.out.println("类名称:"+class3.getName());*/
       
       
           //3、获取一个对象的父类与实现的接口
        /*String  path="Test.Testreflect";
        Class<?> class1=Class.forName(path);*/
           //取得父类
        /*Class<?> class2=class1.getSuperclass();
        System.out.println("class1的父类:"+class2.getName());*/
       
           //获取所有接口
        /*Class<?> ints[] =class1.getInterfaces();
        for (int i = 0; i < ints.length; i++) {
System.out.println((i+1)+" :"+ints[i].getName());
}*/
       
       
       
        //4、获取某个类中的全部构造函数      通过反射机制实例化一个类的对象
        Class<?> class1=Class.forName("com.zking.entity.Person");
             // 第一种方法,实例化默认构造方法,调用set赋值
        /**Person   person=(Person) class1.newInstance();
        person.setPid(1);
        person.setPname("桔梗");
        person.setPsex("女");
        System.out.println(person.toString());*/
         
            // 第二种方法 取得全部的构造函数 使用构造函数赋值
        /**Constructor<?> cons[]=class1.getConstructors();*/
            // 查看每个构造方法需要的参数  
        /**for (int i = 0; i < cons.length; i++) {
        Class<?> class2[] =cons[i].getParameterTypes();
                     System.out.print("cons[" + i + "] (");
                         for (int j = 0; j < class2.length; j++) {
if(j==class2.length-1){
System.out.print(class2[j].getName());
}else{
System.out.print(class2[j].getName()+",");
}
}
                         System.out.println(")");
}
        person=(Person) cons[1].newInstance("name","男");
        System.out.println(person);
        person=(Person) cons[0].newInstance(1,"names","女");
        System.out.println(person);*/
         
         
         
        //5、获取某个类的全部属性
        /** System.out.println("=============本类属性=============");
              //获取本类的全部属性
        Field [] field=class1.getDeclaredFields();
        for (int i = 0; i < field.length; i++) {
          // 权限修饰符
        int  mm=field[i].getModifiers();
        String  pp=Modifier.toString(mm);
          // 属性类型
                        Class<?> t=field[i].getType();
                        System.out.println(pp+"  "+t.getName()+"  "+field[i].getName());
}*/
        /**System.out.println("==========实现的接口或者父类的属性==========");
             // 取得实现的接口或者父类的属性
          Field [] field2=class1.getFields();
          for (int j = 0; j < field2.length; j++) {
        //权限修饰符     
int  hh=field2[j].getModifiers(); 
String kk=Modifier.toString(hh);
Class<?> f=field2[j].getType();
System.out.println(kk+"  "+f.getName()+"  "+field2[j].getName());
}*/
          
          
          
      // 6、获取某个类的全部方法
    /** Method[] method=class1.getMethods(); 
        for (int i = 0; i < method.length; i++) {
        Class<?> returnType=method[i].getReturnType();
        Class<?>  para[] =method[i].getParameterTypes();
        int temp =method[i].getModifiers();
        System.out.print(Modifier.toString(temp)+"  ");
        System.out.print(returnType.getName()+" ");
        System.out.print(method[i].getName()+"  ");
        System.out.print("(");
        for (int k = 0; k < para.length; k++) {
         System.out.print(para[k].getName() + " " + "arg" + k);
                 if (k < para.length - 1) {
                     System.out.print(",");
                 }
}
        Class<?> exce[] =method[i].getExceptionTypes();
        if (exce.length>0) {
System.out.print(") throws");
for (int j = 0; j < exce.length; j++) {
System.out.println(exce[j].getName()+" ");
 if(j<exce.length-1){
 System.out.println(",");
 }
}
}else{
System.out.println(")");
}
        System.out.println(); 
}*/
         
       
       
       //7、通过反射机制调用某个类的方法
       // class1.getMethod("sada");
          // 1》调用TestReflect类中的reflect1方法
       /**Method  method2=class1.getMethod("getPsex");
          Object     object = method2.invoke(class1.newInstance());
          System.out.println(object);
       
       //调用TestReflect的reflect2方法
       method2 = class1.getMethod("setPsex",String.class);
       Object object2= method2.invoke(class1.newInstance(),"张三");
       System.out.println(object2);*/
       
       
       
       //8、通过反射机制操作某个类的属性
         /** Object object=class1.newInstance();
          // 可以直接对 private的属性赋值
          Field   field=class1.getDeclaredField("pname");
          field.setAccessible(true);
          field.set(object, "Java反射机制");
          System.out.println(field.get(object));*/
        
       
       
      //9、反射机制的动态代理
       /**Testreflect   testreflect=new Testreflect();
       System.out.println(testreflect.getClass().getClassLoader().getClass().getName());
       
       MyInvocationHandler  demo=new MyInvocationHandler();
       Subject sub=(Subject) demo.bind(new RealSubject());
       String info=sub.say("爱你", 520);
       System.out.println(info);*/
       
       
       
       
                  //======== 4反射机制的应用实例  ========
          // 4.1 在泛型为Integer的ArrayList中存放一个String类型的对象。
         /** ArrayList<Integer> list=new ArrayList<>();
          Method method=list.getClass().getMethod("add",Object.class);
          method.invoke(list, "Java反射机制实例。");
          int n= method.getModifiers();
          System.out.println(n);
          System.out.println(list.get(0));*/
       
         // 4.2通过反射取得并修改数组的信息
       /*int [] temp={1,2,45,36,48};
       Class<?> demo=temp.getClass().getComponentType();
       System.out.println("数组类型:"+demo.getName());
       System.out.println("数组长度:"+Array.getLength(temp));
       System.out.println("数组的第一个元素: " + Array.get(temp, 0));
       Array.set(temp, 0, 100000);
       System.out.println("修改之后数组第一个元素为: " + Array.get(temp, 0));
       
       
       
       
      Object obj=  Array.newInstance(demo, temp.length);
      int i =Array.getLength(temp);
      System.arraycopy(obj, 0, obj, 0, i); */
       
       
       //4.3通过反射机制修改数组的大小
        /*int[] temp = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
           int[] newTemp = (int[]) arrayInc(temp, temp.length);
           print(newTemp);
           String[] atr = { "a", "b", "c" };
           String[] str1 = (String[]) arrayInc(atr, atr.length);
           print(str1);  */
       
       //4.5将反射机制应用于工厂模式
        /**
        * 对于普通的工厂模式当我们在添加一个子类的时候,就需要对应的修改工厂类。 当我们添加很多的子类的时候,会很麻烦。
        * Java 工厂模式可以参考
        * http://baike.xsoftlab.net/view/java-factory-pattern
       
        * 现在我们利用反射机制实现工厂模式,可以在不修改工厂类的情况下添加任意多个子类。
       
        * 但是有一点仍然很麻烦,就是需要知道完整的包名和类名,这里可以使用properties配置文件来完成。
       
        * java 读取 properties 配置文件 的方法可以参考
        * http://baike.xsoftlab.net/view/java-read-the-properties-configuration-file
       
        * @author xsoftlab.net
        */
        fruit f=Factory.getInstance("Test.Apple");
        if(f!=null){
        f.eat();
        }
       }
       
    // 修改数组大小   
     public static Object arrayInc(Object obj, int len) {
           Class<?> arr = obj.getClass().getComponentType();
           Object newArr = Array.newInstance(arr, len);
           int co = Array.getLength(obj);
           System.arraycopy(obj, 0, newArr, 0, co);
           return newArr;
       }   
       
  // 打印
     public static void print(Object obj) {
         Class<?> c = obj.getClass();
         if (!c.isArray()) {
             return;
         }
         System.out.println("数组长度为: " + Array.getLength(obj));
         for (int i = 0; i < Array.getLength(obj); i++) {
             System.out.print(Array.get(obj, i) + " ");
         }
         System.out.println();
     }
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
     //定义项目接口
       interface Subject {
           public String say(String name, int age);
       }
       
     //定义真实项目
     class  RealSubject    implements  Subject{
@Override
public String say(String name, int age) {
return name+"  "+age;
}
     
     }
     
     
     /**
      * 在java中有三种类类加载器。
      * 
      * 1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。
      * 
      * 2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jrelibext目录中的类
      * 
      * 3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。
      * 
      * 如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。
      * 
      * @author xsoftlab.net
      * 
      */
     class  MyInvocationHandler implements InvocationHandler {
                private  Object  obj=null;
                public  Object  bind(Object obj){
                this.obj=obj;
                return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
                }
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
Object  temp=method.invoke(this.obj, args);
return temp;
}
     
     }
     
     
     
     
     
     interface fruit {
       public abstract void eat();
    }
    class Apple implements fruit {
       public void eat() {
           System.out.println("Apple");
       }
    }
    class Orange implements fruit {
       public void eat() {
           System.out.println("Orange");
       }
    }
    static class Factory {
       public static fruit getInstance(String ClassName) {
           fruit f = null;
           try {
               f = (fruit) Class.forName(ClassName).newInstance();
           } catch (Exception e) {
               e.printStackTrace();
           }
           return f;
       }
    }
}



1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、 1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READmE.文件(md如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值