黑马程序员--java学习之反射总结

---------------------- android培训java培训、期待与您交流! ----------------------

一.反射的概念

反射就是把Java类中的各种成分映射成相应的java类,Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法类是程序的一部分,每个类都有一个Class对象。换言之,每当编写并且编译了一个新类,就会产生一个Class对象(恰当地说,是被保存在一个同名 的。class文件中)。在运行时,当我们想生成这个类的对象时,运行这个程序的Java虚拟机(JVM)首先检查这个类的Class对象是否已经加载。如果尚未加载,JVM就会根据类名查找。class文件,并将其载入,例如Person类代表人,它的实例对象就是张三,李四这样一个个具体的人, Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class

Class类代表java类,它的各个实例对象就是对应各个类在内存中的字节码文件,要得到各个字节码所对应的字节码文件可以有以下方法:类名.class,对象.getClass(),Class.forName((包名)类名)

Class类中定义了一些固定的方法来获取相应的成员的字节码,例如变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是FieldMethodContructorPackage等等。

九种预定义的Class对象:表示八个基本类型和 void。这些类对象由 Java虚拟机创建,与其表示的基本类型同名,即booleanbytecharshortintlongfloatdouble,分别等价于Boolean.TYPE,Byte.TYPE,Character.TYPE,Short.TYPE,Integer.TYPE,Long.TYPE,Float.TYPE,Double.TYPE,Void.TYPE

 

二.构造方法的反射

得到某个类所有的构造方法,例如:

Constructor [] constructors= Class.forName("java.lang.String").getConstructors();

得到某一个构造方法,例如:

Constructor constructor = Class.forName(java.lang.String).getConstructor(StringBuffer.class);

得到构造方法后,即可用构造方法直接获取对象:

通常方式:String str = new String(new StringBuffer("abc"));

反射方式:String str = (String)constructor.newInstance(new StringBuffer("abc"));

 

三.成员变量的反射

ReflectPoint point = new ReflectPoint(1,7);

      Field y = Class.forName("cn.itcast.corejava.ReflectPoint").getField("y");//获得字段y的字节码

      System.out.println(y.get(point));//获得指定对象pointy的值

      Field x = Class.forName("cn.itcast.corejava.ReflectPoint").getDeclaredField("x");

Field即代表某个类中的一个成员变量,即字节码中的一个变量

实例:获取某个类的字段

/*
需求:获取一个类的所有字段
思路:先获取类的字节码文件,再利用getDeclaredFields方法获取所有的变量

*/

import java.lang.reflect.*;  
public class Field1 { 
   private double d; 
   public static final int i = 37; 
   String s = "testing"; 
   String[] s1=new String[]{"0","1","jk"}; 
   int[] in={1,2,3};
   public static void main(String args[]) { 
      try { 
           Class cls = Class.forName("Field1"); 
           Field fieldlist[] = cls.getDeclaredFields(); //获取给定类所有字段即变量
           for (int i = 0; i < fieldlist.length; i++) { 
              Field fld = fieldlist[i]; 
              System.out.println("name = " + fld.getName()); 
              System.out.println("decl class = " + fld.getDeclaringClass()); 
              System.out.println("type = " + fld.getType()); 
              int mod = fld.getModifiers(); //以整数形式返回由此 Field 对象表示的字段的 Java 语言修饰符
              System.out.println("modifiers = " + Modifier.toString(mod)); //Modifier,对类和成员方法,变量解码,把整数形式的java修饰符变成字符串
              System.out.println("-----"); 
              System.out.println(Modifier.FINAL);
              System.out.println(Modifier.ABSTRACT);
              System.out.println(Modifier.isFinal(mod));
              System.out.println("-----"); 
           } 
      } 
      catch (Throwable e) { 
           System.err.println(e); 
      } 
   } 
}

四.成员方法的反射

Method提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。

实例:用反射调用某对象的方法

/*
 需求:用反射机制直接调用特定对象的某方法
 思路:先获取类的字节码文件,利用getmethod方法获取特定参数类型的方法,再利用Method类中的invoke方法执行特定对象,特定参数的方法。
 */
package cn.pengpan.day2;

import java.lang.reflect.*;
public class Method1 
{
	public int meth1(int x,int y)
	{
		return x*y;
	}
	public int meth2(int x,int y,int z)
	{
		return x*y*z;
	}
public static void main(String[] args) 
{
	try {
		Class cls=Class.forName("day5.Method1");
	Class cl1[]=new Class[2];//新建一个数组装入字节码文件
	cl1[0]=Integer.TYPE;
	cl1[1]=Integer.TYPE;
	Method me1=cls.getMethod("meth1", cl1);//得到指定参数列表的方法
	Method1 me2=new Method1();
	Object[] cl2=new Object[2];
	cl2[0]=new Integer(2);
	cl2[1]=new Integer(5);
	Object obj=me1.invoke(me2, cl2);//利用invoke方法执行指定对象指定参数
	Integer in1=(Integer)obj;
	System.out.println(in1.intValue());
	} catch (Throwable e) {
		System.err.println(e);
	}	
}
}

	用反射的方式执行某个类中的main方法:
class TestArguments{
	public static void main(String[] args){
		for(String arg : args){
			System.out.println(arg);
		}
	}
}
class ReflectTest
{
public static void main(String[] args) throws Exception {
TestArguments.main(new String[]{"111","222","333"});
	String startingClassName = args[0];//代表要执行的类名,从控制台输入
	Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
mainMethod.invoke(null, (Object)new String[]{"111","222","333"});//编译器别打散字符串数组,当成一个对象
}
}

五.数组的反射

Array工具类用于完成对数组的反射操作,提供了动态创建和访问 Java 数组的方法。具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class。基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。Arrays.asList()方法处理int[]String[]时的差异:int类型会输出哈希码,String类型会直接打印。

实例:通过反射建立一个string类型的数组

import java.lang.reflect.*;  
public class Array1 { 
   public static void main(String args[]) { 
      try { 
           Class cls = Class.forName("java.lang.String"); //得到String的字节码文件
           Object arr = Array.newInstance(cls, 10); //得到数组对象
           Array.set(arr, 5, "this is a test"); //设值
           String s = (String) Array.get(arr, 5); //得到指定角标位的值
           System.out.println(s); 
      } 
      catch (Throwable e) { 
           System.err.println(e); 
      } 
   } 
} 

---------------------- android培训java培训、期待与您交流! ----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值