原文地址:https://www.cnblogs.com/imdeveloper/p/11787310.html

类对象

类对象指的是一个类在jvm中加载后所形成的对象,每一个类都只有一个类对象,该类对象被所有的实例对象所共享。

类之间有不同的方法,不同的属性。类对象,就是用于描述这种类,都有什么属性,什么方法的。

获取类对象有三种方式:

  1. Class.forName
  2. Hero.class
  3. new Hero().getClass()
Class pClass1 = Class.forName(className);
Class pClass2 = Hero.class;
Class pClass3 = new Hero().getClass();

一个JVM中,一种类,只会有一个类对象存在。所以以上三种方式取出来的类对象,都是一样的(一个ClassLoader下,一种类只会有一个类对象存在。通常一个JVM下,只会有一个ClassLoader

获取类对象的时候,会导致类属性被初始化

无论什么途径获取类对象,都会导致静态属性被初始化,而且只会执行一次。(除了直接使用 Class c = Hero.class 这种方式,这种方式不会导致静态属性被初始化)

反射

与传统的通过new来获取对象的方式不同,反射机制,会先拿到“类对象”,然后通过类对象获取“构造器对象”,再通过构造器对象创建一个对象

//传统的使用new的方式创建对象
Hero h1 =new Hero();
h1.name = "teemo";
System.out.println(h1); try {
//使用反射的方式创建对象,要加包名
String className = "charactor.Hero";
//类对象
Class pClass = Class.forName(className);
//构造器
Constructor c = pClass.getConstructor();
//通过构造器实例化
Hero h2 = (Hero) c.newInstance();
h2.name ="gareen";
System.out.println(h2);
} catch (Exception e) {
e.printStackTrace();
}

通过反射修改属性的值

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

    因为对于private修饰的成员,需要使用field.setAccessible(true)才能访问和修改
  2. 访问并修改
Hero h =new Hero();
//使用传统方式修改name的值为garen
h.name = "garen";
try {
// 获取类Hero的名字叫做name的字段
Field f1 = h.getClass().getDeclaredField("name");
// 修改这个字段的值
// 第一个参数是指定方法所属的实例,同一个类可能有不同属性的实例所以需要指定一下,后面的参数是方法原本需要的参数
f1.set(h, "teemo");
//打印被修改后的值
System.out.println(h.name); } catch (Exception e) {
e.printStackTrace();
}
  • getField 只能获取public的,包括从父类继承来的字段。
  • getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。


    这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true)

通过反射调用方法

  1. 首先为Hero的name属性,增加setter和getter
  2. 通过反射机制调用Hero的setName
Hero h = new Hero();
try {
// 获取这个名字叫做setName,参数类型是String的方法(找不到对应参数方法会报错)
Method m = h.getClass().getMethod("setName", String.class);
// 对h对象,调用这个方法
m.invoke(h, "盖伦");
// 使用传统的方式,调用getName方法
System.out.println(h.getName()); } catch (Exception e) {
e.printStackTrace();
}

反射方式的好处

使用反射方式,首先在src目录下准备一个配置文件,里面存放的是类的名称,和要调用的方法名。在测试类Test中,首先取出类名称和方法名,然后通过反射去调用这个方法。

配置

class = reflection.Service1
method = doService1

使用

//从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);

当需要从调用第一个业务方法,切换到调用第二个业务方法的时候,不需要修改一行代码,也不需要重新编译,只需要修改配置文件,再运行即可。

反射与类对象获取-Java学习的更多相关文章

  1. Java反射02 : Class对象获取的三种方式和通过反射实例化对象的两种方式

    1.Class对象获取的三种方式 本文转载自:https://blog.csdn.net/hanchao5272/article/details/79361463 上一章节已经说过,一般情况下,Jav ...

  2. 模拟实现MyBatis中通过SQL反射实体类对象功能

    话不多说,直接上干货! package cn.test; import java.lang.reflect.Method; import java.sql.Connection; import jav ...

  3. 5.3类集(java学习笔记)集合的输出

    一.集合的输出 迭代输出:Iteratror接口 在输出集合时,最标准的方法是使用迭代器迭代输出. 1,List中的迭代器. Iterator中包含三个方法: hasNex()t判断集合内是否有元素存 ...

  4. 5.2类集(java学习笔记)Map,Set接口

    一.Map接口 Map接口中存储数据是通过key->value的方式成对存储的,可以通过key找到value. 二.Map接口常用子类 1.HashMap HashMap是无序存放的,key不允 ...

  5. 5.1 java类集(java学习笔记)Collection、List接口及ArrayList、LinkedList类。

    一.类集 类集就是一组动态的对象数组,说类集可能不好理解,类集又称容器,容器顾名思义就是放东西的地方. 类集就是为了让我们更加简洁,方便的存放.修改.使用数据的. 二.Collection接口 我们看 ...

  6. JAVA反射机制教程-获取类对象

    1. 什么是类对象 类对象,就是用于描述这种类,都有什么属性,什么方法的 2. 获取类对象 获取类对象有3种方式(1). Class.forName(2). Hero.class(3). new He ...

  7. java学习笔记13--反射机制与动态代理

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note13.html,转载请注明源地址. Java的反射机制 在Java运行时环境中,对于任意 ...

  8. java学习笔记12--异常处理

    java学习笔记系列: java学习笔记11--集合总结 java学习笔记10--泛型总结 java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 j ...

  9. Java 学习(4):基本数据类型,变量类型

    目录 --- 基本数据类型 --- 变量类型 基本数据类型 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间. 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用 ...

随机推荐

  1. CSS的border-radius 设置圆弧

    现象:将div变为有一定幅度的圆形.椭圆形等 方法:使用css的border-radius 属性进行设置CSS3 border-radius 属性:向 div 元素添加圆角边框: 一:首先建立一个di ...

  2. react-native 标题随页面滚动显示和隐藏

    效果图如下: 代码实现: import React, {Component} from 'react'; import { ScrollView, Text, View, FlatList, } fr ...

  3. 炫彩字and鼠标爱心

    <!DOCTYPE html> <style type="text/css"> body{ background-color: black; } #zx { ...

  4. 6.python3实用编程技巧进阶(一)

    1.1.如何在列表中根据条件筛选数据 # 1.1.如何在列表中根据条件筛选数据 data = [-1, 2, 3, -4, 5] #筛选出data列表中大于等于零的数据 #第一种方法,不推荐 res1 ...

  5. 五分钟搞懂什么是B-树(全程图解)【转】

    前戏 我们大家都知道动态查找树能够提高查找效率,比如:二叉查找树,平衡二叉查找树,红黑树.他们查找效率的时间复杂度O(log2n),跟树的深度有关系,那么怎么样才能提高效率呢?当然最快捷的方式就是减少 ...

  6. HttpContext.Current.Server.MapPath("") 未将对象设置到引用的

    在多线程中使用该方法获取目录报错:未将对象设置到引用 #region 上传图片到腾讯 public async Task<Result> UploadImageToWX(string ba ...

  7. C学习笔记(4)--- 指针的应用(第一部分)

    1.指针(pointer)概念: 指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址.就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明.指针变量声明的一般形式为: ...

  8. 通过GL函数处理图片以及其它相关功能

    我们知道在屏幕后处理里面通过 Graphics.Blit 函数可以通过材质处理屏幕图片, 当我们想要处理一般图片的时候, 直接调用GL函数就行了, 按照习惯自己封装一个 Blit 方法 : ) { i ...

  9. vue操作select获取option值

    如何实时的获取你选中的值 只用@change件事 @change="changeProduct($event)" 动态传递参数 vue操作select获取option的ID值 如果 ...

  10. 密标与pdf有什么关系

    密标与pdf有什么关系 密标与pdf有什么关系 密标与pdf有什么关系