反射-》java

为什么要了解java的反射机制

java的反射机制主要是更深入地控制程序的运行过程,可以在程序运行时对用户输入的信息进行验证,还可以逆向控制程序的执行过程。

一.反射

通过JAVA的反射机制,可以访问装载到JVM中的JAVA对象的描述,实现访问检测,修改描述JAVA对象本身信息的功能。

JTextField textfield =new JTextField();
class textFieldC=textField.getClass();

1.1访问构造方法

通过一组方法来访问构造方法:返回Constructor类型的对象或者数组,每个constructor对象代表一个构造方法,利用constructor对象可以操纵相应的构造方法。
具体的constructor类型的介绍可以参考这篇:添加链接描述
下面举个例子:
测试类通过反射访问Demo1类中的所有构造方法,并且将该构造方法是否允许带有可变数量的参数,入口参数类型和可能抛出的异常类型信息输出到控制台。

import java.lang.reflect.*;

import javax.lang.model.type.DeclaredType;
import javax.net.ssl.ExtendedSSLSession;

import FANHE.Demo1;
public class ConstructorDemo1 {
    public static void main(String[]args) {
    	Demo1 demo1=new Demo1("10","20","30");
    	Class<?extends Demo1>demo1Class=demo1.getClass();
    	Constructor[]declaredConstructors=demo1Class.getDeclaredConstructors();
    	for(int i=0;i<declaredConstructors.length;i++) {
    		Constructor<?>constructor=declaredConstructors[i];
    		System.out.println("查看是否允许带有可变数量的参数"+constructor.isVarArgs());
    		System.out.println("查看该构造方法的入口参数类型依次为");
    		Class[]parameterTypes=constructor.getParameterTypes();
    		for(int j=0;j<parameterTypes.length;j++) {
    			System.out.println(""+parameterTypes[j]);
    		}
    		System.out.println("该构造方法可能抛出的异常类型为:");
    		Class[]exceptionTypes=constructor.getExceptionTypes();
    		for(int j=0;j<exceptionTypes.length;j++) {
    			System.out.println(""+exceptionTypes[j]);
    		}
    		Demo1 d2=null;
    		while(d2==null) {
    			try {if(i==2)
    				d2=(Demo1)constructor.newInstance();
    			else if(i==1)
    				d2=(Demo1)constructor.newInstance("7",5);
    			else {
					Object[]parameters=new Object[] {new String[] {"100","200","300"}};
					d2=(Demo1)constructor.newInstance(parameters);
    			}
    			
    		}catch(Exception e) {
    			System.out.println("抛出异常");
    			constructor.setAccessible(true);
    		}
    	}
          if(d2!=null) {
        	  d2.print();
        	  System.out.println();
          }
    	}
    }
}

其中Demo1类的构造如下:

public class Demo1 {
	
		   String s;
		   int i,i2,i3;
		   private Demo1() {}
		   protected Demo1(String s,int i) {
			   this.s=s;
			   this.i=i;
		   }
		   public Demo1(String...strings)throws NumberFormatException{
			   if(0<strings.length)
				   i=Integer.valueOf(strings[0]);
			   if(1<strings.length)
				  i2=Integer.valueOf(strings[1]);
			   if(2<strings.length)
				  i3=Integer.valueOf(strings[2]);
		   }
		   public void print() {
			   System.out.println("s="+s);
			   System.out.println("i="+i);
			   System.out.println("i2="+i2);
			   System.out.println("i3="+i3);
		   }

}

程序运行结果如下:
在这里插入图片描述

1.2访问成员变量

通一组方法来访问类的成员变量:返回Field类型的对象或者数组,每个Field对象代表一个成员变量,利用Field对象可以操纵相应的成员变量。
简单返回成员变量的名称为例:

import java.lang.reflect.Field;



public class FieldDemo {
             public static void main(String[]args) {
            	 Demo2 example=new Demo2();
            	 Class exampleC=example.getClass();
            	 Field[]declaredFields=exampleC.getDeclaredFields();//获取所有的成员变量
            	 for(int i=0;i<declaredFields.length;i++) {
            		 Field field=declaredFields[i];
            		 System.out.println("名称为"+field.getName());
            		 Class fieldType=field.getType();
            	 }
           }
            	 
}

其中成员变量的定义如下:

public class Demo2 {
          int i;
          public float f;
          protected boolean b;
          private String s;
}

输出结果如下:
在这里插入图片描述

1.3访问成员方法

import Fanshe2.Demo3;
import java.lang.reflect.*;
public class MethodDemo {
       public static void main(String[]args) {
    	   Demo3 demo=new Demo3();
    	   Class demoClass=demo.getClass();
    	   Method[]declaredMethod=demoClass.getDeclaredMethods();
    	   for(int i=0;i<declaredMethod.length;i++) {
    		   Method method=declaredMethod[i];
    		   System.out.println("名称为"+method.getName());
    		   System.out.println("是否允许带有可变数量的参数:"+method.isVarArgs());
    		   System.out.println("入口的参数类型依次为");
    		   Class[]parameterTypes=method.getParameterTypes();
    		   for(int j=0;j<parameterTypes.length;j++) {
    			   System.out.println(""+parameterTypes[j]);
    		   }
    		   System.out.println("返回类型为:"+method.getReturnType());
    		   System.out.println("可能抛出的异常类型为:");
    		   Class[]exceptionTypes=method.getExceptionTypes();
    		   for(int j=0;j<exceptionTypes.length;j++) {
    			   System.out.println(""+exceptionTypes[j]);
    		   }
    		   boolean isTurn=true;
    		   while(isTurn) {
    			   try {
    				   isTurn=false;
    				   if("staticMethod".equals(method.getName()))
    					   method.invoke(demo);
    				   else if("publicMethod".equals(method.getName()))
    					   System.out.println("返回值"+method.invoke(demo, 168));
    				   else if("protectedMethod".equals(method.getName())) 
    					   System.out.println("返回值为"+method.invoke(demo, "7",5));
    			       else if ("privateMethod".equals(method.getName())) {
    			    	   Object[]parameters=new Object[] {new String[]{"M","W","Q"}};
    			    	   System.out.println("返回值为"+method.invoke(demo, parameters));
    			       }
    			    	   
    				   }catch(Exception e) {
    					   System.out.println("在执行方法时抛出异常");
    					   method.setAccessible(true);
    					   isTurn=true;
    				   }
    			   }
    		   System.out.println();
    		   }
    	   }
       
}

定义的demo3代码块:

public class Demo3 {
         static void staticMethod() {
        	 System.out.println("执行staticMethod方法");
         }
         
         public int publicMethod(int i) {
        	 System.out.println("执行publicMethod()方法");
        	 return i+100;
         }
         
         protected int protectedMethod(String s,int i) throws NumberFormatException{
        	 System.out.println("执行protectedMethod方法");
        	 return Integer.valueOf(s)+i;
         }
         private String privateMethod(String...strings) {
        	 System.out.println("执行privateMethod()方法");
        	 StringBuffer stringBuffer=new StringBuffer();
        	 for(int i=0;i<strings.length;i++)
        	 {
        		 stringBuffer.append(strings[i]);
        	 }
        	 return stringBuffer.toString();
         }
}

在反射中执行可变数量的参数的构造方法时,需要将入口参数定义成二维数组。Method类的常用方法请自行查阅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值