反射的基石 Class类

  • 对比提问: Person类代表人,它的实例对象就是张三,李四这样一个个具体的人, Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class。对比提问:众多的人用一个什么类表示?众多的Java类用一个什么类表示?
    • 人 Person
    • Java类 Class
  • Class类代表Java类,它的各个实例对象又分别对应什么呢?
    • 对应各个类在内存中的字节码,例如,Person类的字节码,ArrayList类的字节码,等等。
    • 一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的,这一个个的空间可分别用一个个的对象来表示,这些对象显然具有相同的类型,这个类型是什么呢?
  • 何得到各个字节码对应的实例对象( Class类型)
    • 类名.class,例如,System.class
    • 对象.getClass(),例如,new Date().getClass()
    • static Class.forName("类名"),例如,Class.forName("java.util.Date");
      • Class.forName()得到字节码的情况:
           1、字节码已经加载到java虚拟机中,去得到字节码
           2、java虚拟机中还没有生成字节码 用类加载器进行加载,加载的字节码缓冲到虚拟机中
  • 九个预定义Class实例对象:八个基本数据类型和void类型
    • 参看Class.isPrimitive方法的帮助
    • Int.class == Integer.TYPE]
    1. byte.class
    2. char.class
    3. short.class
    4. int.class
    5. long.class
    6. float.class
    7. double.class
    8. boolean.class和
    9. void.class)
  • 数组类型的Class实例对象
    • Class.isArray()
  • 总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如,int[],void…

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

这个类的名字就是Class,要注意与小写class关键字的区别哦。Class类描述了哪些方面的信息呢?

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

学习反射,首先就要明白Class这个类。写如下代码进行对比理解:

        /*Person p1 = new Person("zhangsan");
Person p2 = new Person("lisi");
*/
/*Class x1 = Vector类在内存里的字节码
Class x2 = Date类在内存里的字节码*/
Class x1 = Vector.class;
Class x2 = Date.class;

每个java类都是Class的一个实例对象,它们的内容不同,但是,它们的特征相同,譬如,都有方法,有字段,有父类,有包。

2. ******讲课时要一定画一张图:多个类的字节码装载入内存,在内存中加入一个个方块空间表示字节码,然后用一个个椭圆表示以这个字节码创建出来的实例对象,并用监视代码来说明字节码只被装载一次,而它构造的实例对象的构造方法被调用了多次。

用如下代码更进一步说明Class的实例是什么?是一份字节码,一个类在虚拟机中通常只有一份字节码:

Date d1 = new Date();

Class clazz1 = d1.getClass();

Class clazz2 = Date.class;

Class clazz3 = null;

clazz3 = Class.forName("java.util.Date");

  if(clazz1==clazz2)

  {

      System.out.println(clazz1.getName());

  }

  if(clazz1==clazz3)

  {

      System.out.println(clazz1.getName());

  } 

3.一个奇怪的问题:加载了字节码,并调用了其getMethods之类的方法,但是没有看到类的静态代码块被执行,只有在第一个实例对象被创建时,这个静态代码才会被执行。

准确的说,静态代码块不是在类加载时被调用的,而是第一个实例对象被创建时才执行的。


  • 反射就是把Java类中的各种成分映射成相应的java类。

      • 例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等。
  • 一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,
      • 通过调用Class类的方法可以得到这些实例对象后,得到这些实例对象后有什么用呢?怎么用呢?这正是学习和应用反射的要点。

Constructor类

  • 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"));
    • 反射方式: 
      String str = (String)constructor.newInstance(new StringBuffer("abc"));
    • //调用获得的方法时要用到上面相同类型的实例对象
  • Class.newInstance()方法:
    • 例子:String obj = (String)Class.forName("java.lang.String").newInstance();
    • 该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
    • 该方法内部的具体代码是怎样写的呢?用到了缓存机制来保存默认构造方法的实例对象。

2. 一个类有多个构造方法,用什么方式可以区分清楚想得到其中的哪个方法呢?根据参数的个数和类型,例如,Class.getMethod(name,Class... args)中的args参数就代表所要获取的那个方法的各个参数的类型的列表。重点:参数类型用什么方式表示?用Class实例对象。例如:

int.class,(int []).class

int [] ints = new int[0];

ints.getClass();

Constructor对象代表一个构造方法,大家觉得Constructor对象上会有什么方法呢?得到名字,得到所属于的类,产生实例对象。

3. 讲解创建实例对象时,先应该举例说说通常情况下是怎样做的, String str = new String(new StringBuffer(“abc”));在源程序中用注释方式给出传统方式的代码,以便对比提醒程序阅读者。

然后再说用反射如何做

String str = (String)constructor.newInstance(/*"abc"*/new StringBuffer("abc"));

System.out.println(str);

讲反射方式创建实例对象时,先故意用string作为参数传进去,根据错误让大家感受到确实是那个构造方法,然后再改为传一个StringBuffer类型的参数进去,  String str = (String)constructor.newInstance(/*"abc"*/new StringBuffer("abc"));

好比,我叫来一个吃人不吃草的恐龙,等到它要吃东西时,我得给他送真人去了吧。


关于java reflect的更多相关文章

  1. java reflect 初始学习 动态加载类

    首先要理解Class类: 在java 的反射中,Class.forName("com.lilin.Office") 使用类的全名,这样获取,不仅仅表示了类的类类型,同时还代表着类的 ...

  2. Java反射学习(java reflect)(二)

    ok之前说了Java的反射和反射分析类,那这些东西有神马作用呢,下面就来说应用: 三.运行时使用反射分析对象 简单写一个Employee类,然后利用JAVA反射去取name域,getDeclareFi ...

  3. Java反射学习(java reflect)(一)

    具有能够分析类能力的程序被称为反射,使用反射库可以编写能够动态操纵Java代码的程序. 一.开始 背景:Java运行时系统始终对所有对象维护一个被称为Runtime的类型标识,然后这货save着每个对 ...

  4. java reflect反思总结

    --------------TestBean package lh.demo.bean; public class TestBean {  private String userName;  priv ...

  5. java reflect反射调用方法invoke

    类定义 package Reflect; public class MyTest { public int a; public static int b; public static final in ...

  6. java reflect反射获取方法变量参数

    类的成员包含变量(Field),方法(Method),构造器(Constructor) 类定义 package Reflect; public class MyTest { public int a; ...

  7. Java reflect 反射学习笔记

    1. class 类的使用 万事万物皆对象 (基本数据类型, 静态成员不是面向对象), 所以我们创建的每一个类都是对象, 即类本身是java.lang.Class类的实例对象, 但是这些对象不需要 n ...

  8. Java Reflect

    Method method=demo.getMethod("sayChina");             method.invoke(demo.newInstance());   ...

  9. java reflect反射---Java高级开发必须懂的

    理解反射对学习Java框架有很大的帮助,如Spring框架的核心就是使用Java反射实现的,而且对做一些Java底层的操作会很有帮助.  一.Class类的使用         1.万事万物皆对象,( ...

  10. Java —— Reflect反射机制

    JAVA反射机制是在运行时,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java的反射机制. ...

随机推荐

  1. Java验证码和ajax判断

    关于来了解相关的api BufferedImage(int width, int height, int imageType) 构造一个类型为预定义图像类型之一的 BufferedImage. Buf ...

  2. 今日又遇无法启动apache

    前几天安装了.NET要用到的MSSERVER,之后apache就running none of service. 把微软的MSSERVER停用掉服务就没问题.哪部分冲突了

  3. Can't connect to MySQL server on localhost (10061)解决方法

    出现这种错误的原因是由于MySQL的服务被关闭的原因,重新启动一下服务就可以了,启动服务的操作如下: 右键[计算机]-[管理]

  4. UDP编程

    一: socket编程中的几种地址 Socket编程会遇到三种地址, 都是定义的结构体(struct): Struct in_addr     {         Unsigned int s_add ...

  5. [Redux] Fetching Data on Route Change

    We will learn how to fire up an async request when the route changes. A mock server data: /** /api/i ...

  6. AndroidManifest.xml解释说明和android的启动过程

    1.android清单文件:AndroidManifest.xml 说明如下: <?xml version="1.0" encoding="utf-8"? ...

  7. 使用Java辅助类(CountDownLatch、CyclicBarrier、Semaphore)并发编程

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法 一.C ...

  8. Chapter 3 - How to Move a sprite

    http://www.eoeandroid.com/forum.php?mod=viewthread&tid=250529 http://www.cocos2d-x.org/boards/6/ ...

  9. linux shell less 命令---转

    less 工具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大.less 的用法比起 more 更加的有弹性.在 more 的时候,我们并没有办法向前面翻 ...

  10. thinkphp中session跨域问题

    问题描述 <thinkphp实现短信验证注册>中,小编不止记录了短信验证码的实现方法,同时还记录了图片验证码的实现方法. 本地使用,一切正常:后端项目和前端项目都部署到服务器,一切正常:后 ...