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程序需要某一个类时,如果该类尚未加载到内存中,系统会通过加载.连接.初始化三个步骤将该类加载到内存,并完成初 ...
随机推荐
- jquery如何删除一个元素后面的所有元素
$("div>span:first").nextAll().remove()
- Zend Studio 错误集锦[PHP]
错误信息:Cannot create linked resource '/.org.eclipse.dltk.core.external.folders/.link6'. The parent re ...
- /MT /MD /ML /MTd /MDd /MLd 的区别
Multithreaded Libraries Performance The single-threaded CRT is no longer ( in vs2005 ) available. Th ...
- ubuntu文件定时加密压缩
#!/bin/sh #zip.sh DATE=`date -d yesterday +"%Y%m%d"` #password PASS="123456" if ...
- 在线最优化求解(Online Optimization)之五:FTRL
在线最优化求解(Online Optimization)之五:FTRL 在上一篇博文中中我们从原理上定性比较了L1-FOBOS和L1-RDA在稀疏性上的表现.有实验证明,L1-FOBOS这一类基于梯度 ...
- mybatis中:returned more than one row, where no more than one was expected.异常
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorEx ...
- Http Url Get请求方式需要对中文参数进行编码
public static void main(String[] args) { try { String mytext = java.net.URLEncoder.encode("上海南站 ...
- vi/vim使用指北 ---- Moving Around in a Hurry
上一篇文章中,简单列出了一些基本的Vim操作,也列出了很多的光标移动命令,本章主要是有哪些命令可以更快的移动光标. vim的编辑操作,用得最多就是移动光标,对于很少行的文件来说,基本的命令就够用了,但 ...
- MEAN实践——LAMP的新时代替代方案(下)
在本系列文章的第一部分旨在介绍一些应用程序的基础技术细节和如何进行数据建模,而这个部分文章将着手建立验证应用程序行为的测试,并会指出如何启动和运行应用程序. 首先,编写测试 首先定义一些小型配置库.文 ...
- Flex +WebService
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="h ...