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程序需要某一个类时,如果该类尚未加载到内存中,系统会通过加载.连接.初始化三个步骤将该类加载到内存,并完成初 ...
随机推荐
- 【收藏】win7打开word每次提示配置解决办法
打开“我的电脑”——“ C:\Program Files\Common Files\Microsoft Shared\OFFICE12\Office Setup Controller ”——找到一个“ ...
- 团队项目——特定功能NABC
我们要做的项目是截屏软件,目前决定做电脑端的应用 我觉得这个软件应该具有随意截屏的功能,就是可以用鼠标拖动线条,只要形成闭合图形就可以将线条内的图像截取出来: NABC模型: N(Need): 许多人 ...
- IE点击tif,tiff文件,提示打开而不是查找
IE点击tif或者tiff后缀的文件,提示窗口没有显示打开,而是现实查找.而下载到本地后,又能用acdsee之类的软件双击打开.在tif文件右键-属性中选择了打开程序,在IE中还是依然. 搜索网络资料 ...
- HDU 5781 ATM Mechine 期望dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5781 ATM Mechine Time Limit: 6000/3000 MS (Java/Othe ...
- bzoj 3293 数学整理
和1045一模一样,找到这道题的时候还愣了下神,最后发现样例都是 一样的,直接粘了1045的代码,具体题解看 http://www.cnblogs.com/BLADEVIL/p/3468729.htm ...
- noi2006day2_最大获利 网络流
这道题是上一题的数据加强版,dinic表示毫无压力: #include<iostream> #include<cstdio> #include<cstring> # ...
- web之困:现代web应用安全指南
<web之困:现代web应用安全指南>在web安全领域有“圣经”的美誉,在世界范围内被安全工作者和web从业人员广为称道,由来自google chrome浏览器团队的世界顶级黑客.国际一流 ...
- UML状态图(转载)
概述: 图表本身的名称,阐明该图的目的和其他细节.它描述了在一个系统中的一个组成部分不同的状态.状态是特定的一个系统的组件/对象. 状态图描述了一个状态机.我们阐明的状态机可以被定义为一台机器,它定义 ...
- codeforces #232 div2 解题报告
A:简单题:我们可以把点换成段处理,然后枚举段看是否被霸占了: #include<iostream> #include<]; ]=; ;i<=n;i++) { ...
- IE6下position解决父元素被撑开的问题
在IE6下面当子元素的宽度/高度大于父元素时, 父元素的宽度/高度就被撑开.IE7以上是不会被撑开的 <style> .f{width:100px; height:100px; backg ...