zoukankan      html  css  js  c++  java
  • Class对象和反射

    1.class对象
    在java中一切都是对象,从某种意义上,java中的对象可以分为:实例对象和Class对象。实例对象通过new关键得到,那么Class对象呢?Class对象无法通过new关键字获取,在类加载的过程中,JVM生成一个与加载的字节码文件相关的class对象。通过类名可以获取对应Class对象。class对象主要用来对应类的所有对象。java程序在运行之前并未完全加载,各个类只在需要的时候才将该类加载进内存,生成对应的class对象。

    所有的类都是在对其第一次使用的时候,动态加载到JVM中,当程序创建第一个对类静态成员的引用的时候,就会加载这个。使用new创建类的对象的也会被当做是对类静态成员的引用。因此java程序在它开始运行之前并非被完全加载,其各个部分是在必须的时候才加载。一旦某个类的Class对象被载入内存,它就用来创建这个类的所有的对象。如下面程序所示:

     1 class Test1{
     2     static{
     3         System.out.println("loading1");
     4     }
     5     
     6 }
     7 class Test2{
     8     static{
     9         System.out.println("loading2");
    10     }
    11     
    12 }
    13 class Test3{
    14     static{
    15         System.out.println("loading3");
    16     }
    17     
    18 }
    19 public class Demo {
    20     public static void main(String[] args) {
    21         //new Test1();
    22         Class clz = Test1.class;//注意Class clz = Test1.class;,不会触发静态块的执行,即不会自动初始化该Class对象
    23         try {
    24             
    25             Class.forName("Test2");
    26         } catch (ClassNotFoundException e) {
    27             e.printStackTrace();
    28         }
    29         new Test3();
    30     }
    31     
    32 }

    输出结果:

    loading1
    loading2
    loading3

    2.Class对象的获取

    Class对象是jvm用来保存对象实例对象的相关信息的,除此之外,我们完全可以把Class对象看成一般的实例对象,事实上所有的Class对象都是类Class的实例。获取Class对象主要有三种方式:

     1 /**      
     2 *    获取Class对象的三种方式    
     3 */
     4 public class Demo{
     5     public static void main(String[] args){
     6         //1.通过实例对象获取class对象
     7         Demo demo = new Demo();
     8         Class clsdemo = demo.getClass();
     9         
    10         //2.通过Class的静态方法forName
    11         try {
    12             Class clsdemo2 = Class.forName("Demo");
    13         } catch (ClassNotFoundException e) {
    14             e.printStackTrace();
    15         }
    16         
    17         //3.通过类名和class关键字获取
    18         Class clsdemo3 = Demo.class;
    19     }
    20 }

    3.Class对象的使用和反射
    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。通过反射机制来访问一个类java对象的属性,方法,甚至我们可以轻易改变一个私有成员。java反射是基于Class类和java.lang.Reflect类库。反射机制使得我们可以创建一个编译时完全未知的对象,并调用这个对象的方法。

     1 public class Demo{
     2     public static void main(String[] args){
     3         
     4         Test test = new Test();
     5         System.out.println(test.getClass()==Test.class);//一个类对应的class对象在内存中是唯一的
     6         
     7         Class cls = Test.class;//字节码文件加载进内存,生成class对象,但是不会进行相关的初始化工作,不引起静态块的执行
     8         try {
     9             
    10             Field [] fields = cls.getDeclaredFields();
    11             for (Field field : fields) {
    12                 System.out.println(field);
    13             }
    14             Method [] methods = cls.getDeclaredMethods();
    15             for (Method method : methods) {
    16                 System.out.println(method);
    17             }
    18         } catch (SecurityException e) {
    19             e.printStackTrace();
    20         }
    21     }
    22 }
    23 class Test{
    24     public static int count=0;
    25     private int age=20;
    26     public String name="xm";
    27     static{
    28         System.out.println("类被加载");
    29     }
    30     public void test(){
    31         System.out.println("sss");
    32     }
    33     private void call(){
    34         System.out.println("hi");
    35     }
    36 }
    类被加载
    true
    public static int com.test.demo.Test.count
    private int com.test.demo.Test.age
    public java.lang.String com.test.demo.Test.name
    public void com.test.demo.Test.test()
    private void com.test.demo.Test.call()

     4.泛化的Class引用

    Class引用总是指向某个Class对象,它可以制造实例,并包含可以作用于这些实例的所有方法代码,且包含该类的静态成员,因此Class引用表示的就是它指向的对象的确切类型,而该对象便是Class类的一个对象。class引用可泛化。通过泛型语法,可以让编译器强制的执行额外的类型检查。如果希望放松些限制,可以使用通配符?,表示“任何事物”,如Class<?> intClass = int.class;在java SE5中,Class<?>优于平凡的Class.如下:

    public class Demo {
        public static void main(String[] args) {
            Class intClass = int.class;
            Class<Integer> integerClass = int.class;
            integerClass = Integer.class;
         Class<?> integerClz =
    Integer.class;
    } }
  • 相关阅读:
    计算机网络面试题总结
    为0LTP选择RDMBS时,你都需要考虑哪些?
    Redis集群搭建与简单使用
    Innodb关键特性之自适用Hash索引
    关于MySQL的commit非规律性失败案例的深入分析
    MySQL存储写入性能严重抖动分析
    【Linux】管理文件系统
    【Linux】YUM源搭建
    【Linux】计划任务
    【Linux】日志分析及管理
  • 原文地址:https://www.cnblogs.com/liupiao/p/9259398.html
Copyright © 2011-2022 走看看