5、java反射基础
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反射基础的更多相关文章
- java反射基础知识(四)反射应用实践
反射基础 p.s: 本文需要读者对反射机制的API有一定程度的了解,如果之前没有接触过的话,建议先看一下官方文档的Quick Start. 在应用反射机制之前,首先我们先来看一下如何获取一个对象对应的 ...
- java反射基础知识(一)
一.反射 反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为 ...
- java反射(基础了解)
package cn.itcast_01; /** *Person类 */ public class Person { /** 姓名 */ private String name; ...
- 深入解析Java反射基础
博客原文:http://www.sczyh30.com/posts/Java/java-reflection-1/ - 这老哥写的特别好 一.回顾:什么是反射? 反射(Reflection)是Java ...
- Java 反射基础
1.反射概念: Java运行时,动态获得类的信息以及动态调用对象的方法的功能. 在运行时判断任意一个对象所属的类 在运行时构造任意一个类的对象 在运行时判断任意一个类所具有的成员变量和方法 在运行时调 ...
- java反射基础知识(五)反射应用实践
详解Java反射各种应用 Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息.通过反射获取类的信息,得到类的信息之后,就可以获取以下相关内容: Cl ...
- java反射基础知识(三)
原文地址:http://tutorials.jenkov.com/java-reflection/index.html http://www.cnblogs.com/penghongwei/p/329 ...
- java反射基础知识(二)
1. 了解 Java 中的反射 1.1 什么是 Java 的反射 Java 反射是可以让我们在运行时获取类的函数.属性.父类.接口等 Class 内部信息的机制.通过反射还可以让我们在运行期实例化对象 ...
- 简介Java反射基础
[参考资料: 疯狂Java讲义 Chapter 18] 1.类加载.连接.初始化 当Java程序需要某一个类时,如果该类尚未加载到内存中,系统会通过加载.连接.初始化三个步骤将该类加载到内存,并完成初 ...
随机推荐
- cacti install on ubuntu
安装cacti需要的软件需要 nginx + php + mysql + rrdtool + cacti + snmp 1.nginx 安装配置 首先按照如下命令安装,明显是马虎不细心./config ...
- 安装配置Apache2.4和php7.0
接下来就要进入到PHP的学习了,所以要安装Apache服务器和PHP,从昨天开始一直到刚刚才配置完成,中间也遇到了一些问题,所以整理一下写了下来.接下来就是Win64位系统配置Apache2.4和PH ...
- Linux 下开放指定端口
安装tomcat后,在客户端输入地址 http://localhost:8080/ ,发现默认端口8080不能访问. 由于Linux防火墙默认是关闭8080端口.因此,若要能够访问8080端口,可以 ...
- Beta版软件说明书
软件使用说明书 一. 软件概述 本软件面向广大简易图片使用者,旨在为用户提供简单方便的不对其他软件产生依赖的截图软件,可以脱机使用. 二. 运行环境 个人电脑,Windows7操作系统,. ...
- UVALive - 6952 Cent Savings dp
题目链接: http://acm.hust.edu.cn/vjudge/problem/116998 Cent Savings Time Limit: 3000MS 问题描述 To host a re ...
- Linux sort --copy
Source: http://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html sort是在Linux里非常常用的一个命令,管排序的,集中 ...
- Matlab画柱状和折线对照图
上面是效果图,看着很不错吧,主要的问题在于用XTickLabel设置横坐标时候,横坐标会扩展,就是说如果label是[1 2 3],咱就做了三组试验,参数分别是 1 2 3,但是显示是1 2 ...
- navigationController.navigationBar.titleTextAttributes
navigationController.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObject:[UIColor ...
- 最小PE文件讨论
1.实例1国外的人写的最小的PE文件--97Bytes 4D5A0000504500004C0101006A2A58C30000000000000000040003010B01080004000000 ...
- 【Asp.Net WebFrom】分页
Asp.Net WebForm 分页 一. 前言 Asp.Net WebForm 内置的DataPager让人十分蛋疼 本文使用的分页控件是第三方分页控件 AspNetPager,下载地址: 链接: ...