Class对象:

Class对象记录了所有与类相关的信息,当类加载器从文件系统中加载.class文件到JVM中的同时会为每一个类创建一个Class对象。通过Class对象可以获取到类的属性、方法、构造器等全部与类相关的信息。

现在假设在com.aop包下有一个抽象类和一个类,定义如下:

  1. package com.aop;
  2.  
  3. abstract public class Creature<T> {
  4.  
  5. }
  1. package com.aop;
  2.  
  3. public class Person extends Creature<String>{
  4.  
  5. int id;
  6. public String name;
  7. private int age;
  8.  
  9. public Person() { }
  10. public Person(int age, String name){
  11. this.age = age;
  12. this.name = name;
  13. }
  14.  
  15. public int getId() {
  16. return id;
  17. }
  18.  
  19. public void setId(int id) {
  20. this.id = id;
  21. }
  22.  
  23. public String getName() {
  24. return name;
  25. }
  26.  
  27. public int getAge() {
  28. return age;
  29. }
  30.  
  31. public void setName(String name) {
  32. this.name = name;
  33. }
  34.  
  35. public void setAge(int age) {
  36. this.age = age;
  37. }
  38.  
  39. static public void countAdd(int a, Integer b){
  40. System.out.println(a + " + " + b + " = " + (a+b));
  41. }
  42.  
  43. public void show() {
  44. System.out.println("我是一个人!");
  45. }
  46.  
  47. public void display(String nation) {
  48. System.out.println("我的国际是:" + nation);
  49. }
  50.  
  51. @Override
  52. public String toString() {
  53. return "Person [name=" + name + ", age=" + age + "]";
  54. }
  55.  
  56. }

很简洁,定义一个带泛型的抽象类,Person继承自该抽象类。

与反射相关的包:

import java.lang.reflect.Constructor;  //与构造器相关
import java.lang.reflect.Field;      //与域相关
import java.lang.reflect.Method;      //与方法相关

//还有其它的...

1、Class对象的4中获取方式:

  1. package com.aop;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class TestReflection {
  6.  
  7. @Test
  8. public void testReflection() throws Exception{
  9.  
  10. //1.调用运行时类本身的.class属性
  11. Class<Person> clazz1 = Person.class;
  12.  
  13. //2.通过运行时类的对象获取
  14. Person person = new Person();
  15. Class<? extends Person> clazz2 = person.getClass();
  16.  
  17. //3.通过Class的静态方法获取.通过此方式,体会一下,反射的动态性。
  18. String className = "com.aop.Person";
  19.  
  20. Class<?> clazz3 = Class.forName(className);
  21.  
  22. //4.(了解)通过类的加载器
  23. ClassLoader loader = this.getClass().getClassLoader();
  24. Class<?> clazz4 = loader.loadClass(className);
  25.  
  26. System.out.println(clazz1.getName());
  27. System.out.println(clazz2.getName());
  28. System.out.println(clazz3.getName());
  29. System.out.println(clazz4.getName());
  30.  
  31. System.out.println(clazz1 == clazz2);
  32. System.out.println(clazz1 == clazz3);
  33. System.out.println(clazz1 == clazz4);
  34. }
  35. }

2、通过反射读取对象的属性值,并修改它们(能够读取与修改包括private权限的属性值)

  1. @Test
  2. public void testField() throws Exception{
  3. String className = "com.aop.Person";
  4. Class<?> clazz = Class.forName(className);
  5.  
  6. Person person = (Person) clazz.newInstance();
  7.  
  8. //getField(...)方法会获取public类型的属性,包括父类的public类型属性都能获取
  9. Field field = clazz.getField("name");
  10. field.set(person, "东东");
  11. System.out.println(person);
  12.  
  13. //getDeclaredField(...)获取所有所有类型的属性,但是,不包括父类的属性在内
  14. Field field2 = clazz.getDeclaredField("age");
  15. //如果类中的属性设定为private或者是“默认类型”,则需要设置其可访问属性
  16. field2.setAccessible(true);
  17. field2.set(person, 100);
  18. System.out.println(person);
  19.  
  20. }

3、通过反射调用对象的方法

  1. @Test
  2. public void testMethod() throws Exception{
  3. String className = "com.aop.Person";
  4. Class<?> clazz = Class.forName(className);
  5.  
  6. Person person = new Person(50, "哈哈");
  7.  
  8. //获取并调用无参的show方法
  9. Method method1 = clazz.getMethod("show");
  10. method1.invoke(person);
  11.  
  12. //获取并调用有参的display方法
  13. Method method2 = clazz.getMethod("display", String.class);
  14. method2.invoke(person, "中国");
  15.  
  16. //调用有返回值的方法
  17. Method method3 = clazz.getMethod("toString");
  18. Object resultVal = method3.invoke(person);
  19. System.out.println(resultVal);
  20.  
  21. //调用有参数的静态方法
  22. Method method4 = clazz.getMethod("countAdd", int.class, Integer.class);
  23. method4.invoke(Person.class, 10, 100);
  24. }

4、通过反射调用带参构造器来实例化一个对象

  1. @Test
  2. public void testConstructor() throws Exception{
  3. String className = "com.aop.Person";
  4. Class<?> clazz = Class.forName(className);
  5.  
  6. //调用一个有参的构造器
  7. Constructor<?> cons = clazz.getConstructor(int.class, String.class);
  8. Person person = (Person) cons.newInstance(20, "兮兮");
  9. System.out.println(person);
  10. }

5、获取“父类”、“带泛型的父类”、“父类的泛型

  1. @Test
  2. public void testGeneric() throws Exception{
  3. String className = "com.aop.Person";
  4. Class<?> clazz = Class.forName(className);
  5.  
  6. //1、获取父类,只能得到父类的名称
  7. Class<?> superClazz = clazz.getSuperclass();
  8. System.out.println(superClazz);
  9.  
  10. //2、获取带泛型的父类
  11. Type type = clazz.getGenericSuperclass();
  12. System.out.println(type);
  13.  
  14. //3、获取父类的泛型类(重要)
  15. ParameterizedType param = (ParameterizedType)type;
  16. Type[] argmts = param.getActualTypeArguments();
  17. Class<?> claz = (Class<?>)argmts[0];
  18. System.out.println(claz);
  19. }

下面是全部的源代码:

  1. package com.aop;
  2.  
  3. abstract public class Creature<T> {
  4.  
  5. }

abstract public class Creature

  1. package com.aop;
  2.  
  3. public class Person extends Creature<String>{
  4.  
  5. int id;
  6. public String name;
  7. private int age;
  8.  
  9. public Person() { }
  10. public Person(int age, String name){
  11. this.age = age;
  12. this.name = name;
  13. }
  14.  
  15. public int getId() {
  16. return id;
  17. }
  18.  
  19. public void setId(int id) {
  20. this.id = id;
  21. }
  22.  
  23. public String getName() {
  24. return name;
  25. }
  26.  
  27. public int getAge() {
  28. return age;
  29. }
  30.  
  31. public void setName(String name) {
  32. this.name = name;
  33. }
  34.  
  35. public void setAge(int age) {
  36. this.age = age;
  37. }
  38.  
  39. static public void countAdd(int a, Integer b){
  40. System.out.println(a + " + " + b + " = " + (a+b));
  41. }
  42.  
  43. public void show() {
  44. System.out.println("我是一个人!");
  45. }
  46.  
  47. public void display(String nation) {
  48. System.out.println("我的国际是:" + nation);
  49. }
  50.  
  51. @Override
  52. public String toString() {
  53. return "Person [name=" + name + ", age=" + age + "]";
  54. }
  55.  
  56. }

public class Person extends Creature

  1. package com.aop;
  2.  
  3. import java.lang.reflect.Constructor;
  4. import java.lang.reflect.Field;
  5. import java.lang.reflect.Method;
  6. import java.lang.reflect.ParameterizedType;
  7. import java.lang.reflect.Type;
  8.  
  9. import org.junit.Test;
  10.  
  11. public class TestReflection {
  12.  
  13. @Test
  14. public void testReflection() throws Exception{
  15.  
  16. //1.调用运行时类本身的.class属性
  17. Class<Person> clazz1 = Person.class;
  18.  
  19. //2.通过运行时类的对象获取
  20. Person person = new Person();
  21. Class<? extends Person> clazz2 = person.getClass();
  22.  
  23. //3.通过Class的静态方法获取.通过此方式,体会一下,反射的动态性。
  24. String className = "com.aop.Person";
  25.  
  26. Class<?> clazz3 = Class.forName(className);
  27.  
  28. //4.(了解)通过类的加载器
  29. ClassLoader loader = this.getClass().getClassLoader();
  30. Class<?> clazz4 = loader.loadClass(className);
  31.  
  32. System.out.println(clazz1.getName());
  33. System.out.println(clazz2.getName());
  34. System.out.println(clazz3.getName());
  35. System.out.println(clazz4.getName());
  36.  
  37. System.out.println(clazz1 == clazz2);
  38. System.out.println(clazz1 == clazz3);
  39. System.out.println(clazz1 == clazz4);
  40. }
  41.  
  42. @Test
  43. public void testField() throws Exception{
  44. String className = "com.aop.Person";
  45. Class<?> clazz = Class.forName(className);
  46.  
  47. Person person = (Person) clazz.newInstance();
  48.  
  49. //getField(...)方法会获取public类型的属性,包括父类的public类型属性都能获取
  50. Field field = clazz.getField("name");
  51. field.set(person, "东东");
  52. System.out.println(person);
  53.  
  54. //getDeclaredField(...)获取所有所有类型的属性,但是,不包括父类的属性在内
  55. Field field2 = clazz.getDeclaredField("age");
  56. //如果类中的属性设定为private或者是“默认类型”,则需要设置其可访问属性
  57. field2.setAccessible(true);
  58. field2.set(person, 100);
  59. System.out.println(person);
  60.  
  61. }
  62.  
  63. @Test
  64. public void testMethod() throws Exception{
  65. String className = "com.aop.Person";
  66. Class<?> clazz = Class.forName(className);
  67.  
  68. Person person = new Person(50, "哈哈");
  69.  
  70. //获取并调用无参的show方法
  71. Method method1 = clazz.getMethod("show");
  72. method1.invoke(person);
  73.  
  74. //获取并调用有参的display方法
  75. Method method2 = clazz.getMethod("display", String.class);
  76. method2.invoke(person, "中国");
  77.  
  78. //调用有返回值的方法
  79. Method method3 = clazz.getMethod("toString");
  80. Object resultVal = method3.invoke(person);
  81. System.out.println(resultVal);
  82.  
  83. //调用有参数的静态方法
  84. Method method4 = clazz.getMethod("countAdd", int.class, Integer.class);
  85. method4.invoke(Person.class, 10, 100);
  86. }
  87.  
  88. @Test
  89. public void testConstructor() throws Exception{
  90. String className = "com.aop.Person";
  91. Class<?> clazz = Class.forName(className);
  92.  
  93. //调用一个有参的构造器
  94. Constructor<?> cons = clazz.getConstructor(int.class, String.class);
  95. Person person = (Person) cons.newInstance(20, "兮兮");
  96. System.out.println(person);
  97. }
  98.  
  99. @Test
  100. public void testGeneric() throws Exception{
  101. String className = "com.aop.Person";
  102. Class<?> clazz = Class.forName(className);
  103.  
  104. //1、获取父类,只能得到父类的名称
  105. Class<?> superClazz = clazz.getSuperclass();
  106. System.out.println(superClazz);
  107.  
  108. //2、获取带泛型的父类
  109. Type type = clazz.getGenericSuperclass();
  110. System.out.println(type);
  111.  
  112. //3、获取父类的泛型类(重要)
  113. ParameterizedType param = (ParameterizedType)type;
  114. Type[] argmts = param.getActualTypeArguments();
  115. Class<?> claz = (Class<?>)argmts[0];
  116. System.out.println(claz);
  117. }
  118.  
  119. }

public class TestReflection

参考:尚硅谷java视频

5、java反射基础的更多相关文章

  1. java反射基础知识(四)反射应用实践

    反射基础 p.s: 本文需要读者对反射机制的API有一定程度的了解,如果之前没有接触过的话,建议先看一下官方文档的Quick Start. 在应用反射机制之前,首先我们先来看一下如何获取一个对象对应的 ...

  2. java反射基础知识(一)

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

  3. java反射(基础了解)

    package cn.itcast_01; /** *Person类 */ public class Person {    /** 姓名 */    private String name;     ...

  4. 深入解析Java反射基础

    博客原文:http://www.sczyh30.com/posts/Java/java-reflection-1/ - 这老哥写的特别好 一.回顾:什么是反射? 反射(Reflection)是Java ...

  5. Java 反射基础

    1.反射概念: Java运行时,动态获得类的信息以及动态调用对象的方法的功能. 在运行时判断任意一个对象所属的类 在运行时构造任意一个类的对象 在运行时判断任意一个类所具有的成员变量和方法 在运行时调 ...

  6. java反射基础知识(五)反射应用实践

    详解Java反射各种应用   Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息.通过反射获取类的信息,得到类的信息之后,就可以获取以下相关内容: Cl ...

  7. java反射基础知识(三)

    原文地址:http://tutorials.jenkov.com/java-reflection/index.html http://www.cnblogs.com/penghongwei/p/329 ...

  8. java反射基础知识(二)

    1. 了解 Java 中的反射 1.1 什么是 Java 的反射 Java 反射是可以让我们在运行时获取类的函数.属性.父类.接口等 Class 内部信息的机制.通过反射还可以让我们在运行期实例化对象 ...

  9. 简介Java反射基础

    [参考资料: 疯狂Java讲义 Chapter 18] 1.类加载.连接.初始化 当Java程序需要某一个类时,如果该类尚未加载到内存中,系统会通过加载.连接.初始化三个步骤将该类加载到内存,并完成初 ...

随机推荐

  1. cacti install on ubuntu

    安装cacti需要的软件需要 nginx + php + mysql + rrdtool + cacti + snmp 1.nginx 安装配置 首先按照如下命令安装,明显是马虎不细心./config ...

  2. 安装配置Apache2.4和php7.0

    接下来就要进入到PHP的学习了,所以要安装Apache服务器和PHP,从昨天开始一直到刚刚才配置完成,中间也遇到了一些问题,所以整理一下写了下来.接下来就是Win64位系统配置Apache2.4和PH ...

  3. Linux 下开放指定端口

    安装tomcat后,在客户端输入地址  http://localhost:8080/ ,发现默认端口8080不能访问. 由于Linux防火墙默认是关闭8080端口.因此,若要能够访问8080端口,可以 ...

  4. Beta版软件说明书

    软件使用说明书 一.    软件概述 本软件面向广大简易图片使用者,旨在为用户提供简单方便的不对其他软件产生依赖的截图软件,可以脱机使用. 二.    运行环境 个人电脑,Windows7操作系统,. ...

  5. UVALive - 6952 Cent Savings dp

    题目链接: http://acm.hust.edu.cn/vjudge/problem/116998 Cent Savings Time Limit: 3000MS 问题描述 To host a re ...

  6. Linux sort --copy

    Source: http://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html sort是在Linux里非常常用的一个命令,管排序的,集中 ...

  7. Matlab画柱状和折线对照图

        上面是效果图,看着很不错吧,主要的问题在于用XTickLabel设置横坐标时候,横坐标会扩展,就是说如果label是[1 2 3],咱就做了三组试验,参数分别是 1 2 3,但是显示是1 2 ...

  8. navigationController.navigationBar.titleTextAttributes

    navigationController.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObject:[UIColor ...

  9. 最小PE文件讨论

    1.实例1国外的人写的最小的PE文件--97Bytes 4D5A0000504500004C0101006A2A58C30000000000000000040003010B01080004000000 ...

  10. 【Asp.Net WebFrom】分页

    Asp.Net WebForm 分页 一. 前言 Asp.Net WebForm 内置的DataPager让人十分蛋疼 本文使用的分页控件是第三方分页控件 AspNetPager,下载地址: 链接: ...