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程序需要某一个类时,如果该类尚未加载到内存中,系统会通过加载.连接.初始化三个步骤将该类加载到内存,并完成初 ...
随机推荐
- UITableView基本使用和cell的属性
在ios的UI中UITableView是个常用且强大的控件 基本使用: 1>设置代理,一般把控制器设为代理:self.tableView.delegate = self; 2>遵守代理的协 ...
- 教你怎么把安卓应用软件放到系统根目录system/app下
安卓手机有时候安装的软件多了,用着久了就会出现卡机,死机的现象,流畅度大大的减弱了,实在是影响使用体验.对于这种情况,有的人会经常清理后台程序,可是次数多了,提速的效果也不太明显.那么,到底怎么做才能 ...
- 【桌面程序搞界面再也不怕了】:迅雷BOLT入门(一)开篇 附程序和源码
本来想多蛤一下前因后果,突然意兴阑珊不想多说啦,直接帖效果吧. 这个是用迅雷BOLT把原来写的一个IE拦截器的界面重写了一下.界面效果是直接从单位的大屏系统改过来的,其中文本框部分,还请设计大屏的小姑 ...
- 使用 NIO.2 遍历目录下所有的Java文件
package wellGrounded; import java.io.IOException; import java.nio.file.FileVisitResult; import java. ...
- mysql的简单主从复制(ubuntu)
环境:两台ubuntu 12.04.5 虚拟机 mysql-server-5.5 master (192.168.240.130) slave (192.168.240.129) (1)查看二进 ...
- 【bzoj1007】[HNOI2008]水平可见直线
1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5932 Solved: 2254[Submit][Sta ...
- jquery 常用组件的小代码
获得所有复选框的值 function getAllValue() { var str=""; $("input[name='checkbox']:checkbox&quo ...
- VS开发工具 不会在异常的地方停止的问题.
启用"仅我的代码"
- YTKNetwork
YTKNetwork 是猿题库 iOS 研发团队基于 AFNetworking 封装的 iOS 网络库,其实现了一套 High Level 的 API,提供了更高层次的网络访问抽象. YTKNetwo ...
- codeforces #240 div 2
A:语文题,估计大家都会, B题:假如答案是ans,求最大的ans,是w*a/b==(w-ans)*a/b; 明显的二分,可是我的二分写的没水准,还有是直接做: #include<string. ...