zoukankan      html  css  js  c++  java
  • 反射机制:类对象

     
      类对象
    概念

    所有的类,都存在一个类对象。(在一个JVM中,一种类,只会有一个类对象存在。)

    用途

    提供类本身的信息。

    (比如有几种构造方法, 有多少属性,有哪些普通方法。)

    和普通对象的区别 打比方,如果类对象是描述数据的结构,普通对象就是描述数据。

    获取类对象

    (三种方式)

    (均返回Class类型)

    1、Class pClass1=Class.forName(className【包名.类名】);

    2、Class PClass2=【类名】.class;//这种方式不会导致静态属性被初始化

    3、Class PClass3=new 【类名】().getClass();

    注意:以上三种方式取出来的类对象,都是一样的。

     类属性

    (在静态初始化块中被初始化,

    而且只会执行一次)

    1、被static修饰的属性叫类属性,也叫静态属性。

         static String copyright;

    2、获取类对象时,类属性会被初始化

         static {//静态初始化块
               System.out.println("初始化 copyright");
               copyright = "版权由Riot Games公司所有";
         }

     创建对象

    (指普通对象)

    1、传统方式:通过new 来获取对象。

    2、反射机制:先拿到类对象——>获取构造器对象——>在创建对象。(三步走)

    (1)Class pClass=Class.forName(className【包名.类名】);

    (2)Constructor  c=pClass【类对象】.getConstructor();

    (3)【类名】 h=(【类名】) c.newInstance();

    ***********************************************************

    通过配置文件获取对象。

    (1)首先准备一个文本文件hero.config。文本里写着charactor.APHero 或者是charactor.ADHero。

    APHero.java
    ADHero.java

    (2)设计一个方法叫做:public static Hero getHero();

    View Code

    (3)通过打印h,可以发现,当配置文件里的内容发生变化的时候,就会得到不同的对象。

    View Code

    源代码不需要发生任何变化,只需要修改配置文件,就可以导致程序的逻辑发生变化, 这是一种基于配置的编程思想

    Spring框架中的IOC和DI的底层就是基于这样的机制实现的。

    注意:(3)步骤中得到的普通对象,指向(2)步骤中创建出来的对象。

    所以(3)中的对象改变会导致(2)中的对象也同样改变。

     访问属性

    (通过反射机制,修改对象的属性)

    1、 为了访问属性,把name修改为public。

    View Code

    2、通过反射,修改属性的值。

    (1)获取类Hero的名字叫做name的字段
    Field f1= new Hero().getClass()【类对象】.getDeclaredField("name");
    (2)修改这个字段的值
    f1【字段对象】.set(h【普通对象】, "teemo");

    View Code

    **************************************************************************

    getField和getDeclaredField的区别:

    getField 只能获取public的,包括父类继承来的字段。

    getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。 (注: 这里只能获取到private字段,但并不能访问该private字段的值,除非加上setAccessible(true))。

     调用方法

    (通过反射机制,调用一个对象的方法)

    1、 为Hero的name属性,增加setter和getter。

    View Code

    2、通过反射机制,调用Hero的setName。

    (1)获取这个名字叫做setName,参数类型String方法

    Method m=new Hero().getClass()【类对象】.getMethod("setName",String);

    (2)对h对象,调用这个方法

    m.invoke(【普通对象】h,【方法参数】"盖伦");

     反射机制有什么用

     1、准备一个配置文件,叫做spring.txt。

    【类的名称】class=reflection.Service1

    【要调用的方法名】method=doService1

    2、首先取出类名称和方法名,然后创建普通对象和要调用的方法对象,最后通过反射去调用这个方法。

    public class Test {
     
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public static void main(String[] args) throws Exception {
     
            //从spring.txt中获取类名称和方法名称
            File springConfigFile = new File("e:\project\j2se\src\spring.txt");
            Properties springConfig= new Properties();
            springConfig.load(new FileInputStream(springConfigFile));
            String className = (String) springConfig.get("class");
            String methodName = (String) springConfig.get("method");
             
            //根据类名称获取类对象
            Class clazz = Class.forName(className);
            //根据方法名称,获取方法对象
            Method m = clazz.getMethod(methodName);
            //获取构造器
            Constructor c = clazz.getConstructor();
            //根据构造器,实例化出对象
            Object service = c.newInstance();
            //调用对象的指定方法
            m.invoke(service);
             
        }
    }
    View Code
       
  • 相关阅读:
    [编写高质量代码:改善java程序的151个建议]建议72 生成字列表后不要再操作原列表
    [编写高质量代码:改善java程序的151个建议]建议71 推荐使用subList处理局部列表
    [编写高质量代码:改善java程序的151个建议]建议70 子列表只是原列表的一个视图
    程序员的简历到底该怎么写?(转)
    SQL数据库数据优化SQL优化总结( 百万级数据库优化方案)
    sqlserver的四种分页方式
    sql server中截取字符串的常用函数(自己经常到用的时候想不起来所以拿到这里)
    SQL之存储过程详细介绍及语法(篇幅比较长慢慢看)
    超经典SQL练习题,做完这些你的SQL就过关了
    SqlServer 数据库引擎优化顾问优化数据库(消耗内存很大)
  • 原文地址:https://www.cnblogs.com/Strugglinggirl/p/12942412.html
Copyright © 2011-2022 走看看