黑马程序员_反射

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

一、反射的基石(class类)

     Java类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性的值是什么,则是由这个类的实例对象来确定的,不同的实例对象有不同的属性值。Java程序中的各个Java类,它们是否属于同一类事物,是不是可以用一个类来描述这类事物呢?这个类的名字就是Class。

     Class类代表Java所有的类,它的各个实例对象又分别对应各个类在内存中的字节码(一个类在虚拟机中通常只有一份字节码);一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的。
     
       获得各个字节码自己对应的实例对象( Class类型)的方式:
  1. 类名.class,例如,Person.class
  2. 对象.getClass(),例如,new Date().getClass()
  3. Class.forName("类名"),例如,Class.forName("java.util.Date");

二、反射的概念

     反射就是把Java类中的各种成分映射成相应的java类
       一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象后,来获得其中的变量,方法,构造方法,修饰符,包等信息。


三、反射的应用
     
1、  Constructor类( 代表某个类中的一个构造方法)
  •  得到某个类所有的构造方法:
               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"));

   反射方式:Constructor  ctt= String.class.getConstructor(StringBuffer.class);
                            String str = (String) ctt.newInstance(new  StringBuffer("abc"  ));
                                    //调用获得的方法时要用到上面相同类型的实例对象
  •           Class.newInstance()方法:
    该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。



2、 Field 类(代表某个类中的一个成员变量)

//定义一个类

public class ReflectPoint {

      private int x;

      public int y;

      public ReflectPoint(int x, int y) {

            super();

            this.x = x;

            this.y = y;

      }

}

ReflectPoint pt1 = new ReflectPoint(3,5);
//创建一个对象指向ReflectPoint中的成员变量y;
//fieldY不是对象身上的变量,而是类上,字段fieldY 代表的是y的定义
Field fieldY = pt1.getClass().getField( "y");
         
System.  out.println(fieldY.get(pt1));
          
 //取私有变量
Field fieldX = pt1.getClass().getDeclaredField("x"  );
fieldX.setAccessible(  true);//暴力破解
System.  out.println(fieldX.get(pt1));

//设置y的值
fieldY.set( pt1   , 6);

3、Method类(代表某个类中的一个成员方法)

  •           得到类中的某一个方法:
Method charAt  =  Class.forName("java.lang.String").getMethod("charAt",  int.class);

  • 调用方法:
通常方式:System.out.println(str.charAt(1));

反射方式://getMethod  返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
        Method methodCharAt = String. class  .getMethod( "charAt"   int .  class );
        System.  out  .println(methodCharAt.invoke(str1, 1));
                如果传递给 Method 对象的 invoke() 方法的第一个参数为 null ,说明该 Method 对象对应的是一个静态方法!

调用main方法://运行时要带com.itcast.day1.TestArguments参数,通过字符串,得到类的字节码,得到main方法
       
String startingClassName = args[0];
//Class.forName返回与带有给定字符串名的类或接口相关联的 Class 对象
Method mainMethod = Class.forName(startingClassName ).getMethod(  "main"  , String[]. class  );
mainMethod.invoke(  null  , new   Object[]{  new  String[]{ "aaa"  , "bbb"   , "ccc"   }});
mainMethod.invoke(  null  ,(Object)  new  String[]{ "aaa"  , "bbb"   , "ccc"   });
4、反射的作用à实现框架功能
 
  • 框架与框架要解决的核心问题:

                   框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类。

  • 框架要解决的核心问题:

     在程序中无法直接new  某个类的实例对象了,而要用反射方式来做。
config.properties

className= java.util.HashSet
 


import   java.io.*;
import   java.util.Collection;
import   java.util.Properties;

import   com.itcast.day1.ReflectPoint;


public   class   ReflectTest {
      public   static   void   main(String []args)   throws   Exception{
             //加载配置文件(放在包下或者子包中),类加载器
             //getRealPath();//***/*内部
             //一定要记住用完整的路径,完整的路径不是硬编码,而是运算出来的。
             //InputStream ips = new FileInputStream("config.properties");
             //InputStream ips = ReflectTest.class.getClassLoader().getResourceAsStream("config.properties");
             //InputStream ips = ReflectTest.class.getResourceAsStream("config.properties");
          
          InputStream ips = ReflectTest. class .getResourceAsStream( "/config.properties"   );
          
          Properties props =   new   Properties(); //创建一个无默认值得空属性列表。
          
          props.load(ips);
          
          ips.close();
             //用指定的键在此属性列表中搜索属性
          String className = props.getProperty( "className"   );
           Class clas = Class.forName (className);
           Collection collections = (Collection) clas.newInstance();
          
             //Collection collections = new HashSet();
          
          ReflectPoint p1 =   new   ReflectPoint(3,3);
          ReflectPoint p2 =   new   ReflectPoint(5,5);
          ReflectPoint p3 =   new   ReflectPoint(3,3);
          
           collections.add(p1);
           collections.add(p2);
           collections.add(p3);
          
          System.   out .println(collections.size());
          
          
     }
}

 

 
 

 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值