反射技术其实就是动态加载一个指定的类,并获取该类中的所有内容。而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员,简单来说:反射技术可以对一个类进行解剖,反射大大增强了应用程序的可扩展性。

反射技术的原理如下图所示:

但是要想要对字节码文件进行解剖,必须要有字节码文件对象. 如何获取字节码文件对象呢?

要读取的类文件源码:

 package Reflect;

 public class Person {

     /**
* @param args
*/
private String name;
private int age;
public Person(){
System.out.println("Construcor run..");
}
public Person(String name,int age){
this.name=name;
this.age=age;
System.out.println("Person param run...");
}
public static void method(){
System.out.println("method run...");
}
public static void paramMethod(String name,int age){
System.out.println("name="+name+"age:"+age);
}
public static void staticMethod(){
System.out.println("static run");
}
public void show(){
System.out.println(name+"Method show run.."+age);
} }

获取字节码文件对象有三种方式:

(1)
 /*
  * 获取字节码对象的方式:
  * 1,Object类中的getClass()方法的。
  * 想要用这种方式,必须要明确具体的类,并创建对象。
  * 麻烦 
  */

 public static void getObject_1() {
Person p=new Person();
Class<? extends Person> classz=p.getClass();
System.out.println(classz);
Person p1=new Person();
Class<? extends Person> classz1=p.getClass();
System.out.println(classz1);
System.out.println(classz==classz1);
}

(2)
 /*
  * 方式二:
  * 任何数据类型(基本数据类型和引用数据类型)都具备一个静态的属性.class来获取其对应的Class对象。
  * 相对简单,但是还是要明确用到类中的静态成员。
  * 还是不够扩展。
  *
  */

 public  static void getObject_2() {

         Class classz=Person.class;
Class classz1=Person.class;
System.out.println(classz==classz1);
}

(3)

/*
  * 方式三:
  * 只要通过给定的类的 字符串名称就可以获取该类,更为扩展。
  * 可是用Class类中的方法完成。
  * 该方法就是forName.
  * 这种方式只要有名称即可,更为方便,扩展性更强。
  */

 public  static void getObject_3() throws ClassNotFoundException {
String classname="Reflect.Person";
Class classz=Class.forName(classname);
System.out.println(classz);
}

获取Class中的构造函数初始化对象:

(1)调用空参数的构造函数:使用Class类中的newInstance()方法

 //早期:new时候,先根据被new的类的名称找寻该类的字节码文件,并加载进内存,
  // 并创建该字节码文件对象,并接着创建该字节文件的对应的Person对象.

   //现在:
String name = "cn.itcast.bean.Person";
//找寻该名称类文件,并加载进内存,并产生Class对象。
Class clazz = Class.forName(name);
//如何产生该类的对象呢?
Object obj = clazz.newInstance();

(2)调用带参数的构造函数:先要获取指定参数列表的构造函数对象,然后通过该构造函数的对象的newInstance(实际参数)进行对象的初始化

/*
* 当获取指定名称对应类中的所体现的对象时,
* 而该对象初始化不使用空参数构造该怎么办呢?
* 既然是通过指定的构造 函数进行对象的初始化,
* 所以应该先获取到该构造函数。 通过字节码文件对象即可完成。
* 该方法是:getConstructor(paramterTypes);
*
*/
 //带参数初始化新创建的对象
public static void createNewObject_param() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
String classname="Reflect.Person";
Class classz=Class.forName(classname);
Constructor constructor=classz.getConstructor(String.class,int.class);
constructor.newInstance("Java",30);
}

获取反射类的字段:

     public static void getFiledDemo() throws ClassNotFoundException,
NoSuchFieldException, SecurityException, InstantiationException,
IllegalAccessException {
Class classz = Class.forName("Reflect.Person");
Field field = null;
field = classz.getDeclaredField("age");
field.setAccessible(true);
Object obj = classz.newInstance();
field.set(obj, 89);
Object o = field.get(obj);
System.out.println(o);
}

获取反射类的成员方法:

(1)获取空参数一般方法

 private static void getMethodDemo_2() throws Exception {
Class clazz = Class.forName("Reflect.Person"); Method method = clazz.getMethod("show", null);// 获取空参数一般方法。 // Object obj = clazz.newInstance();
Constructor constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("linux", 37); method.invoke(obj, null);
}

(2)获取带参数的一般方法

 private static void getMethodDemo_3() throws Exception {

         Class clazz = Class.forName("Reflect.Person");

         Method method = clazz.getMethod("paramMethod", String.class, int.class);

         Object obj = clazz.newInstance();

         method.invoke(obj, "Ruby", 89);
}

(3)获取反射类的公有、私有方法

 private static void getMethodDemo() throws ClassNotFoundException {
Class classz = Class.forName("Reflect.Person");
Method[] methods = classz.getMethods();// 获取反射类中所有共有的方法
methods = classz.getDeclaredMethods();// 获取本类中包括私有的所有的方法
for (Method method : methods) {
System.out.println(method);
}
}

本文为博主原创文章,转载请注明出处:http://www.cnblogs.com/ysw-go/
1、本博客的原创原创文章,都是本人平时学习所做的笔记,如有错误,欢迎指正。
2、如有侵犯您的知识产权和版权问题,请通知本人,本人会即时做出处理文章。
3、本博客的目的是知识交流所用,转载自其它博客或网站,作为自己的参考资料的,感谢这些文章的原创人员

Java反射机制(获取Class对象的三种方式+获取Class中的构造函数进行对象的初始化+获取反射类的字段+获取反射类的一般方法)的更多相关文章

  1. spring中创建bean对象的三种方式以及作用范围

    时间:2020/02/02 一.在spring的xml配置文件中创建bean对象的三种方式: 1.使用默认构造函数创建.在spring的配置文件中使用bean标签,配以id和class属性之后,且没有 ...

  2. Java反射机制(创建Class对象的三种方式)

    1:SUN提供的反射机制的类: java.lang.Class<T> java.lang.reflect.Constructor<T> java.lang.reflect.Fi ...

  3. Java反射获取class对象的三种方式,反射创建对象的两种方式

    Java反射获取class对象的三种方式,反射创建对象的两种方式 1.获取Class对象 在 Java API 中,提供了获取 Class 类对象的三种方法: 第一种,使用 Class.forName ...

  4. Java反射学习-2 - 获取Class对象的三种方式

    package cn.tx.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import ...

  5. Java反射机制(创建Class对象的三种方式)

    1:了解什么是反射机制? 在通常情况下,如果有一个类,可以通过类创建对象:但是反射就是要求通过一个对象找到一个类的名称:   2:在反射操作中,握住一个核心概念: 一切操作都将使用Object完成,类 ...

  6. Java反射获取类对象的三种方式

    package demo01; /* * 获取一个类的class文件对象的三种方式 * 1.对象获取 * 2.类名获取 * 3.Class类的静态方法获取 */ public class Reflec ...

  7. 反射:获取Class对象的三种方式

    获取Class对象的三种方式 package lianxiApril18; /** * 获取Class对象的三种方式 * 1 Object ——> getClass(); * 2 任何数据类型( ...

  8. 反射应用和获取Class对象的三种方式

    一.写一个"框架",可以创建任何对象运行任何方法 1.配置文件 2.使用类加载器ClassLoader,Properties集合是可以和IO流结合使用完成读取和写入数据的集合,方法 ...

  9. Java Class类以及获取Class实例的三种方式

    T - 由此 Class 对象建模的类的类型.例如,String.class 的类型是Class<String>.如果将被建模的类未知,则使用Class<?>.   publi ...

  10. JDBC 创建连接对象的三种方式 、 properties文件的建立、编辑和信息获取

    创建连接对象的三种方式 //第一种方式 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ ...

随机推荐

  1. Side-by-side assembly

    Side-by-side technology is a standard for executable files in Windows 98 Second Edition, Windows 200 ...

  2. jmeter 响应结果分析一

    转自:http://www.cnblogs.com/Carrie_Liang/archive/2008/11/05/1327604.html Jmeter测试结果分析这一篇,我打算分成上下两部分.上篇 ...

  3. http://wenku.baidu.com/link?url=UGoPtZviipHzi5SDIlGx6hPFWAHTPLFXcZ7ieD15JMd81DEHqjehvphVMhqELmOK4qXR74dTT9nW8VBoApBc7Kfb1ZWrNF_i24fY1YRHVki

    http://wenku.baidu.com/link?url=UGoPtZviipHzi5SDIlGx6hPFWAHTPLFXcZ7ieD15JMd81DEHqjehvphVMhqELmOK4qXR ...

  4. C#字符串的常用操作

    一.string关键字与StringBuilder类 C# 字符串是使用 string 关键字声明的一个字符数组.字符串是使用引号声明的,如下例所示: string s = "Hello, ...

  5. POJ1573——Robot Motion

    Robot Motion Description A robot has been programmed to follow the instructions in its path. Instruc ...

  6. linux应用程序问题

    ---- 1 ----

  7. NFC(8)关于新买的标签的格式化

    有多种方法格式化nfc标签设备. 如搜相关的手机上应用,在应用里选择格式类型 本文是用代码手动格式 public void writeNFCTag(Tag tag) { if (tag == null ...

  8. POI2001 Gold mine(二叉排序树 黑书经典)

    采矿(KOP) 金矿的老师傅年底要退休了.经理为了奖赏他的尽职尽责的工作,决定送他一块长方形地.长度为S,宽度为W.老师傅可以自己选择这块地.显然其中包含的采金点越多越好.你的任务就是计算最多能得到多 ...

  9. KindEditor设置为过滤模式,但在代码模式下提交表单时不过虑HTML标签的解决方法

    KindEditor设置filterMode为true,但在代码模式下提交表单的话,发现并没有过虑掉自己不想保留的HTML标签. 这时只需同步内容前加上红色部分内容即可: onClick=" ...

  10. Treeview控件的Node节点延迟加载

    Treeview控件是一个很常用的控件,用于展示资源或者组织结构的时候很方便,通常会在系统启动时进行资源的加载和节点目录的初始化,但在资源较多和层级较深的情况下,所有节点加载出来会耗费太多时间,影响体 ...