Class对象:

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

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

package com.aop;

abstract public class Creature<T> {

}
 package com.aop;

 public class Person extends Creature<String>{

     int id;
public String name;
private int age; public Person() { }
public Person(int age, String name){
this.age = age;
this.name = name;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public int getAge() {
return age;
} public void setName(String name) {
this.name = name;
} public void setAge(int age) {
this.age = age;
} static public void countAdd(int a, Integer b){
System.out.println(a + " + " + b + " = " + (a+b));
} public void show() {
System.out.println("我是一个人!");
} public void display(String nation) {
System.out.println("我的国际是:" + nation);
} @Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
} }

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

与反射相关的包:

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

//还有其它的...

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

 package com.aop;

 import org.junit.Test;

 public class TestReflection {

     @Test
public void testReflection() throws Exception{ //1.调用运行时类本身的.class属性
Class<Person> clazz1 = Person.class; //2.通过运行时类的对象获取
Person person = new Person();
Class<? extends Person> clazz2 = person.getClass(); //3.通过Class的静态方法获取.通过此方式,体会一下,反射的动态性。
String className = "com.aop.Person"; Class<?> clazz3 = Class.forName(className); //4.(了解)通过类的加载器
ClassLoader loader = this.getClass().getClassLoader();
Class<?> clazz4 = loader.loadClass(className); System.out.println(clazz1.getName());
System.out.println(clazz2.getName());
System.out.println(clazz3.getName());
System.out.println(clazz4.getName()); System.out.println(clazz1 == clazz2);
System.out.println(clazz1 == clazz3);
System.out.println(clazz1 == clazz4);
}
}

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

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

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

 @Test
public void testMethod() throws Exception{
String className = "com.aop.Person";
Class<?> clazz = Class.forName(className); Person person = new Person(50, "哈哈"); //获取并调用无参的show方法
Method method1 = clazz.getMethod("show");
method1.invoke(person); //获取并调用有参的display方法
Method method2 = clazz.getMethod("display", String.class);
method2.invoke(person, "中国"); //调用有返回值的方法
Method method3 = clazz.getMethod("toString");
Object resultVal = method3.invoke(person);
System.out.println(resultVal); //调用有参数的静态方法
Method method4 = clazz.getMethod("countAdd", int.class, Integer.class);
method4.invoke(Person.class, 10, 100);
}

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

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

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

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

下面是全部的源代码:

 package com.aop;

 abstract public class Creature<T> {

 }

abstract public class Creature

 package com.aop;

 public class Person extends Creature<String>{

     int id;
public String name;
private int age; public Person() { }
public Person(int age, String name){
this.age = age;
this.name = name;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public int getAge() {
return age;
} public void setName(String name) {
this.name = name;
} public void setAge(int age) {
this.age = age;
} static public void countAdd(int a, Integer b){
System.out.println(a + " + " + b + " = " + (a+b));
} public void show() {
System.out.println("我是一个人!");
} public void display(String nation) {
System.out.println("我的国际是:" + nation);
} @Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
} }

public class Person extends Creature

 package com.aop;

 import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import org.junit.Test; public class TestReflection { @Test
public void testReflection() throws Exception{ //1.调用运行时类本身的.class属性
Class<Person> clazz1 = Person.class; //2.通过运行时类的对象获取
Person person = new Person();
Class<? extends Person> clazz2 = person.getClass(); //3.通过Class的静态方法获取.通过此方式,体会一下,反射的动态性。
String className = "com.aop.Person"; Class<?> clazz3 = Class.forName(className); //4.(了解)通过类的加载器
ClassLoader loader = this.getClass().getClassLoader();
Class<?> clazz4 = loader.loadClass(className); System.out.println(clazz1.getName());
System.out.println(clazz2.getName());
System.out.println(clazz3.getName());
System.out.println(clazz4.getName()); System.out.println(clazz1 == clazz2);
System.out.println(clazz1 == clazz3);
System.out.println(clazz1 == clazz4);
} @Test
public void testField() throws Exception{
String className = "com.aop.Person";
Class<?> clazz = Class.forName(className); Person person = (Person) clazz.newInstance(); //getField(...)方法会获取public类型的属性,包括父类的public类型属性都能获取
Field field = clazz.getField("name");
field.set(person, "东东");
System.out.println(person); //getDeclaredField(...)获取所有所有类型的属性,但是,不包括父类的属性在内
Field field2 = clazz.getDeclaredField("age");
//如果类中的属性设定为private或者是“默认类型”,则需要设置其可访问属性
field2.setAccessible(true);
field2.set(person, 100);
System.out.println(person); } @Test
public void testMethod() throws Exception{
String className = "com.aop.Person";
Class<?> clazz = Class.forName(className); Person person = new Person(50, "哈哈"); //获取并调用无参的show方法
Method method1 = clazz.getMethod("show");
method1.invoke(person); //获取并调用有参的display方法
Method method2 = clazz.getMethod("display", String.class);
method2.invoke(person, "中国"); //调用有返回值的方法
Method method3 = clazz.getMethod("toString");
Object resultVal = method3.invoke(person);
System.out.println(resultVal); //调用有参数的静态方法
Method method4 = clazz.getMethod("countAdd", int.class, Integer.class);
method4.invoke(Person.class, 10, 100);
} @Test
public void testConstructor() throws Exception{
String className = "com.aop.Person";
Class<?> clazz = Class.forName(className); //调用一个有参的构造器
Constructor<?> cons = clazz.getConstructor(int.class, String.class);
Person person = (Person) cons.newInstance(20, "兮兮");
System.out.println(person);
} @Test
public void testGeneric() throws Exception{
String className = "com.aop.Person";
Class<?> clazz = Class.forName(className); //1、获取父类,只能得到父类的名称
Class<?> superClazz = clazz.getSuperclass();
System.out.println(superClazz); //2、获取带泛型的父类
Type type = clazz.getGenericSuperclass();
System.out.println(type); //3、获取父类的泛型类(重要)
ParameterizedType param = (ParameterizedType)type;
Type[] argmts = param.getActualTypeArguments();
Class<?> claz = (Class<?>)argmts[0];
System.out.println(claz);
} }

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. Travis-CI的初步了解和测试程序的进一步编写

    一. Travis-CI部分 最近基本都在研究Travis-CI的使用.CI是continue integration(持续集成)的缩写,Travis应该是给我们提供免费服务器的组织.下面介绍一下其使 ...

  2. C/C++常用头文件及函数汇总

    转自: C/C++常用头文件及函数汇总 C/C++头文件一览 C #include <assert.h> //设定插入点#include <ctype.h> //字符处理#in ...

  3. windows和linux环境下制作U盘启动盘

    新笔记本上,要装xp的系统,100%会破坏原有的Linux系统,因为安装xp的时候会自动覆盖硬盘的主引导扇区,这个扇区一旦被重写,那么原有的linux根本就启动不了. 要想玩linux和xp双系统,一 ...

  4. android 开发Parcelable 怎么传值ArrayList

    public class TradeEntity implements Parcelable{ public String id; //有关进度条的参数 ArrayList<TradeState ...

  5. ZBar之自定义二维码扫描

    // // YvanQRCodeViewController.m // zBar // // Created by City--Online on 15/6/8. // Copyright (c) 2 ...

  6. 基于ArcEngine的空间数据通用建库软件介绍

    最近花了点时间把之前的空间数据入库功能进行了完善,在这里做一个简单的介绍,也希望大家给提点意见和建议,我的目标是做一个好用.易用.通用.稳定的入库程序. 1.软件特点: 基于模板(方案)的数据更新   ...

  7. File "/struts-tags" not found

    前言 由于在某个jsp引用了struts标签库,导致该错误产生--这是stuts项目算是一道经典错误,往往最后的解决方式是更换Tomcat.今天我记录的是引起这一错误的一个非常隐藏的原因. 错误描述 ...

  8. AC自动机学习

    今天包括这一周开始学习AC自动机了,有点晚,但我感觉努努力还来得及.4月份还得认认真真攻图论,加油! 为2个月后的邀请赛及省赛.东北赛做准备. 推荐AC自动机学习地址:http://www.cppbl ...

  9. BZOJ 2301 Problem b

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2301 冬令营听了莫比乌斯,这就是宋老师上课讲的例题咯[今天来实现一下] #include& ...

  10. BZOJ2694: Lcm

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2694 题解:令f[i]表示i是否有平方因子,则f[i]是积性函数,mu[i]表示莫比乌斯函数. ...