黑马程序员——Java中的反射技术

本文深入探讨Java反射机制的概念、应用以及实现方法,包括获取Class对象、动态创建对象、访问字段与方法等内容,并通过实例代码展示如何在实际开发中灵活运用反射特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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



反射机制


Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class

Class描述了哪些方面的信息呢?

类的名字    类的访问属性    类所属于的包名       字段名称的列表   方法名称的列表等。



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

  对于任意一个对象,都能够调用它的任意一个方法和属性。

  这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。

  动态获取类中信息,就是Java反射。

  以理解为对类的解剖。 


使用反射技术,应该导入的包是java.reflect.*;

反射会导致程序的性能严重下降


反射概述图例:




获取Class对象的三种方式:

/*方式一:

 * 获取字节码对象的方式:

 * 1Object类中的getClass方法。

 * 想要用这种方式,必须要明确具体的类,并创建对象。

 * */

public staticvoidgetClassObject_1()

{

   Personp = newPerson();

   Classclazz = p.getClass();

   Personp1 = newPerson();

   Classclazz1 = p1.getClass();

   System.out.println(clazz==clazz1);

}

/*方式二:

 * 2、任何数据类型都具备一个静态的属性.class来获取其对应的class对象。

 * 相对简单,但是还是要需要明确用到类中的静态成员。

 * 还是不够扩展。

 * */

public staticvoidgetClassObject_2()

{

   Classclazz = Person.class;

   Classclazz1 = Person.class;

   System.out.println(clazz==clazz1); 

}


/*方式三:

 * 重点掌握。

 * 只要通过给定的类的字符串名称就可以获取该类,更为扩展。

 * 可以用Class类中的方法完成。

 * 该方法就是forName.

 * 这种方式只要有名称即可,更为方便,扩展性更强。

 * */

public staticvoidgetClassObject_3() throws ClassNotFoundException

{

   Stringclassname = "cn.itcast.bean.Person";

   Classclazz = Class.forName(classname);

   System.out.println(clazz);

}


图例:


 


Class.forName()的作用?就是返回字节码

返回的方式有两种:

1,这份字节码曾经被加载过,已经待在java虚拟机中了,就可以直接返回了

2java虚拟机中还没有这份字节码,则用类加载器去加载,把加载进来的字节码,缓存到虚拟机中,以后要得到这个字节码就不用在加载了。



Class中的构造函数


public staticvoidcreateNewObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException

   {

      Stringname = "cn.itcast.bean.Person";

      //找寻该名称类文件,并加载进内存,并产生Class对象。

      Classclazz = Class.forName(name);

      //如何产生该类的对象呢?

      Objectobj = clazz.newInstance();

   }

   public static void createNewObject_1() throws ClassNotFoundException,SecurityException, NoSuchMethodException, IllegalArgumentException,InstantiationException, IllegalAccessException, InvocationTargetException

   {

      /*当获取指定名称对应类中所体现的对象时,

       * 而该对象初始化不使用空参数构造该怎么办呢?

       * 既然是通过指定的构造函数进行对象的初始化。

       * 所以应该先获取到该构造函数。通过字节码文件对象完成即可。

       * 该方法是:getConstructor(paramterType);

       * */

      Stringname = "cn.itcast.bean.Person";

      //找寻该名称类文件,并加载进内存,并产生Class对象。

      Classclazz = Class.forName(name);

      //获取到了指定的构造函数对象。

      Constructorconstructor = clazz.getConstructor(String.class,int.class);

      //通过该构造器对象的newInstance方法进行对象的初始化。

      Objectobj = constructor.newInstance("小二",23);

       } 


Class中的字段

/*获取字节码文件中的字段。

    *

    * */

   public static void getFieldDemo() throws SecurityException,NoSuchFieldException, ClassNotFoundException, InstantiationException,IllegalAccessException

   {

      Classclazz = Class.forName("cn.itcast.bean.Person");

      java.lang.reflect.Fieldfield = clazz.getDeclaredField("age");

      //System.out.println(field);     

      //对私有字段的访问取消权限检查。暴力访问。

      field.setAccessible(true);

      Objectobj = null;

      try {

        obj= clazz.newInstance();

        field.set(obj,89);

      }catch(Exception e1) {

        // TODO Auto-generated catch block

        e1.printStackTrace();

      }    

      Objecto = null;

      try {

        o= field.get(obj);

      }catch(IllegalArgumentException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

      }

      System.out.println(o);  

   }


/*获取指定Class中的所有公共函数。

    *

    * */

   public static void getMethodDemo() throws Exception

   {

      Classclazz = Class.forName("cn.itcast.bean.Person");

      Method[]methods = clazz.getMethods();//获取的都是公有的方法。

      methods= clazz.getDeclaredMethods();//获取本类中所有方法,包含私有。

      for(Method method :methods)

      {

        System.out.println(method);

      }    

   }

   public static void getMethodDemo_1() throws Exception

   {

      Classclazz = Class.forName("cn.itcast.bean.Person");

      Methodmethods = clazz.getMethod("show", null);//获取空参数的一般方法。

      //Object obj = clazz.newInstance();

      Constructorconstructor = clazz.getConstructor(String.class,int.class);

      Objectobj = constructor.newInstance("小明",44);

      methods.invoke(obj,null);

   }

   //获取有参数的方法。

   public static void getMethodDemo_2() throws Exception

   {

      Classclazz = Class.forName("cn.itcast.bean.Person");

      Methodmethods = clazz.getMethod("paramMethod", String.class,int.class);

      Objectobj = clazz.newInstance();

      methods.invoke(obj,"小王",55);       

       }

 


反射练习:

public classReflcetTest {

   /**

    * @param args

    * @throws Exception

    */

   public static void main(String[] args) throws Exception {

      // TODO Auto-generated method stub

      Mainboardmb = newMainboard();

      mb.run();

      //不用new完成,而是只获取Class文件,在内部实现创建对象的动作。

      FileconfigFile = newFile("pci.properties");

      Propertiespro = newProperties();

      FileInputStreamfis = newFileInputStream(configFile);

      pro.load(fis);

      for(intx=0;x<pro.size();x++)

      {

        StringpciName = pro.getProperty("pci"+(x+1));

        Classclazz = Class.forName(pciName);//Class类去加载这个PCI子类。

        PCIp = (PCI)clazz.newInstance();

        mb.uesPCI(p);

      }

      fis.close();    

   }

}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值