目录
1.Class类的介绍
反射是干啥的:
反射就是一个可以认清“自己”的方式
通过这个方式,可以得到一个类的信息,就像照镜子来获取自己的外貌信息一样。
反射是reflect 在java.lang.reflect包中。
使用方法:
- 类名.class 如:Class cls=String.class
- 对象.getClass() 如:String str="abcde"; Class cls=str.getClass();
- Class.forName(类的全名) 如:Class cls=Class.forName("java.lang.String");
组成部分 | 访问方法 | 还回值类型 | 解释 |
---|---|---|---|
包路径 | getPackage() | Package对象 | 获得类的存放路径 |
类名称 | getName() | String对象 | 获得类的名称 |
继承类 | getSuperclass() | Class对象 | 获得该类的继承的类就是父类 |
实现接口 | getInterfaces() | Class型数组 | 获得该类实现的所有接口 |
构造方法 | getConstructors() | Constructor型数组 | 获得所有public权限的构造方法 |
getConstructor() | Constructor对象 | 获得指定的public权限的构造方法 | |
getDeclaredConstrutors() | Constructor型数组 | 获得所有的构造方法并按顺序还回 | |
getDeclaredConstrutor() | Constructor对象 | 获得指定的构造方法 | |
方法 | getMethods() | Method型数组 | 获得所有权限为public的方法 |
getMethod() | Method对象 | 获得指定的权限为public的方法 | |
getDeclaredMethods() | Method型数组 | 获得所有的方法,并按顺序还回 | |
getDeclaredMethod() | Method对象 | 获得指定的方法 | |
成员变量 | getFields() | Field型数组 | 获得所有权限为public的成员变量 |
getField() | Field对象 | 获得指定的权限为public的成员变量 | |
getDeclaredFields() | Field型数组 | 获得所有的成员变量,并按顺序还回 | |
getDeclaredField() | Field对象 | 获得指定的成员变量 | |
内部类 | getClasses() | Class型数组 | 获得所有权限为public的内部类 |
getDeclaredClasses() | Class型数组 | 获得所有的内部类 | |
内部类声明类 | getDeclaredClass() | Class对象 | 如果该类是内部类就还回他的成员类,否则就还回null |
2.通过反射访问构造方法
访问构造方法:要用到Constructor类,构造方法如下
- getConstructors()
- getConstructor(Class<?>...parameterTypes)
- getDeclaredConstructors()
- getDeclaredConstructor(Class<?>...parameterTypes)
例如:class.getConstructor(String.class,int.class)或者
class.getConstructor(new Class[]{String.class,int.class})具体应用看下面的帮助理解实例
方法 | 解释 |
---|---|
isVarArgs() | 查看构造方法是否允许带有多个可变参数,还回值类型是布尔型 |
getParameterTypes() | 按照声明顺序以Class数组的形式获得该构造方法的各种参数类型 |
getExceptionTypes() | 以Class数组的形式获得该构造方法可能抛出异常类型 |
newInstance(Object...initargs) | 通过该构造方法利用指定参数创建一个该类的对象,如果未设置参数这表示采用了无参构造方法 |
setAccessible(boolean flag) | 如果该构造方法的权限为private,默认为不允许通过反射利用newInstance(Object...initargs)方法创建对象。如果先执行该方法,并将参数设置为true,则允创建 |
getModifiers() | 获取可以解析出构造方法所采用的修饰符的整数 |
getModifiers()方法解析修饰符类型
静态方法 | 解释 |
---|---|
isPublic(int mod) | 查看修饰符是否有public,是还回true,反之还回false |
isProtected(int mod) | 查看修饰符是否有protected,是还回true,反之还回false |
isLPrivate(int mod) | 查看修饰符是否有private,是还回true,反之还回false |
isStatic(int mod) | 查看修饰符是否有static,是还回true,反之还回false |
isFinal(int mod) | 查看修饰符是否有final,是还回true,反之还回false |
isString(int mod) | 查看修饰符是否有string,是还回true,反之还回false |
具体应用看文章最下方的实例
3.通过反射访问成员变量
访问成员变量主要是Field类,构造方法:
- getFields()
- getField(String name)
- getDeclaredFields()
- getDeclaredField(String name)
方法 | 说明 |
---|---|
getName() | 获得成员变量名字 |
getType() | 获得表示该成员变量类型的Class对象 |
get(Object obj) | 获得指定对象的成员变量的值,还回值是Object类型 |
set(Object obj,Object value) | 将指定对象的成员变量的值设置为value |
getInt(Object obj) | 获得指定对象的成员变量中类型为int的值 |
setInt(Object obj,int i) | 将指定对象的成员变量中类型为int的值设置i |
getFloat(Object obj) | 获得指定对象的成员变量中类型为float的值 |
setFloat(Object obj,float f) | 将指定对象的成员变量中类型为float的值设置f |
getBoolean(Object obj) | 获得指定对象的成员变量中类型为iboolean的值 |
setBoolean(Object obj,boolean z) | 将指定对象的成员变量中类型为boolean的值设置z |
setAccessible(boolean flag) | 此方法可以设置是否忽略权限限制直接访问private等私有权限的成员变量 |
getModifiers | 获取可以解析出成员变量所采用的修饰符的整数 |
具体应用同样看最下方的实例
4.通过反射访问方法
访问方法的主要类是Method,构造方法与前面的类似
- getMethods()
- getMethod(String name,Class<?>...parameterTypes)
- getDeclaredMethods()
- getDeclaredMethod(String name,Class<?>...parameterTypes)
方法 | 说明 |
---|---|
getName() | 获取方法的名称 |
getParameter | 按照声明的顺序以Class数组的形式获得该方法的各个参数 |
getReturnType() | 以Class对象的形式获得该方法的还回值类型 |
getExceptionType() | 以Class数组的形式获得该方法可能抛出的异常类型 |
invoke(Object obj,Object..args) | 利用指定参数args执行指定对象obj中的的该方法,还回值是Object类型的 |
isVarArgs() | 查看该构造方法是否允许带有可变数量的参数,如果允许则还回true,否则还回false |
getModifiers() | 获取可以解析出方法所采用的修饰符的整数 |
5.帮助理解的实例
代码:
Test1类:
package com.a.cn;
interface b{
public void b();
}
interface a{
int a=0;
public void setA(int a);
}
public class Test1 implements a,b{
int x=0;
double y=1.2d;
public Test1(){
System.out.println(2);
}
public Test1(int i){
System.out.println(i);
}
public static void main(String[] args) {
Test1 test1=new Test1();
test1.setA(8);
test1.b();
Test1 test11=new Test1(3);
System.out.println(a);
}
@Override
public void setA(int a) {
System.out.println(a);
}
@Override
public void b() {
System.out.println(1);
}
}
接口a:
package com.a.cn;
interface b{
public void b();
}
interface a{
int a=0;
public void setA(int a);
}
public class Test1 implements a,b{
int x=0;
double y=1.2d;
public Test1(){
System.out.println(2);
}
public Test1(int i){
System.out.println(i);
}
public static void main(String[] args) {
Test1 test1=new Test1();
test1.setA(8);
test1.b();
Test1 test11=new Test1(3);
System.out.println(a);
}
@Override
public void setA(int a) {
System.out.println(a);
}
@Override
public void b() {
System.out.println(1);
}
}
接口b:
package com.a.cn;
interface b{
public void b();
}
interface a{
int a=0;
public void setA(int a);
}
public class Test1 implements a,b{
int x=0;
double y=1.2d;
public Test1(){
System.out.println(2);
}
public Test1(int i){
System.out.println(i);
}
public static void main(String[] args) {
Test1 test1=new Test1();
test1.setA(8);
test1.b();
Test1 test11=new Test1(3);
System.out.println(a);
}
@Override
public void setA(int a) {
System.out.println(a);
}
@Override
public void b() {
System.out.println(1);
}
}
Test类:
package com.a.cn;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test {
public static void main(String[] args) throws NoSuchMethodException {
//创建String对象
String str=new String();
Class string=str.getClass();
System.out.println("获取该类的存放路径:"+string.getPackage());
System.out.println("获取该类的名称:"+string.getName());
System.out.println("获取该类的继承类:"+string.getSuperclass());
//访问构造方法Constructor类
//创建Test1对象
Test1 test1=new Test1();
//创建Class对象
Class te=test1.getClass();
//创建Class类型的数组
Class[] classes=te.getInterfaces();
//foreach遍历
for (Class c:classes) {
System.out.println("获取该类的接口:"+c);
}
//创建Constructor类型的数组
Constructor[] constructor=te.getConstructors();
for (Constructor b:constructor) {
System.out.println("获取该类的构造方法:"+b);
}
Constructor constructor1=te.getConstructor(int.class);
System.out.println("获取该类指定的构造方法:"+constructor1);
System.out.println("查看该构造方法是否允许带有可变数量的参数"+constructor1.isVarArgs());
Class[] classes1=constructor1.getParameterTypes();
System.out.println("第一个声明的参数类型:"+classes1[0]);
/*Modifier类的用法,通过getModifiers()方法获取一个int类型的数还回值,
通过isPublic()或者其他方法解析出修饰符类型,其实还回值是1代表的是public,2代表的是private,等等
其他的都可以自己尝试一下
*/
int modifiers=constructor1.getModifiers();
System.out.println("还回值类型是"+modifiers);
boolean ispublic= Modifier.isPublic(modifiers);
System.out.println("查看该构造方法是否是public类型:"+ispublic);
//访问成员变量Field方法
Field[] fields=te.getDeclaredFields();
int i=0;
for (Field f:fields
) {
i++;
System.out.println("第"+i+"个成员变量名称"+f.getName());
System.out.println("第"+i+"个成员变量类型"+f.getType());
}
//访问方法
Method[] methods=te.getMethods();
int o=0;
for (Method m:methods
) {
o++;
System.out.println("第"+o+"个法的名称是"+m.getName());
System.out.println("第"+o+"个法的还回值类型是"+m.getReturnType());
}
}
}
Test运行结果:
获取该类的存放路径:package java.lang, Java Platform API Specification, version 1.8
获取该类的名称:java.lang.String
获取该类的继承类:class java.lang.Object
2
获取该类的接口:interface com.a.cn.a
获取该类的接口:interface com.a.cn.b
获取该类的构造方法:public com.a.cn.Test1(int)
获取该类的构造方法:public com.a.cn.Test1()
获取该类指定的构造方法:public com.a.cn.Test1(int)
查看该构造方法是否允许带有可变数量的参数false
第一个声明的参数类型:int
还回值类型是1
查看该构造方法是否是public类型:true
第1个成员变量名称x
第1个成员变量类型int
第2个成员变量名称y
第2个成员变量类型double
第1个法的名称是setA
第1个法的还回值类型是void
第2个法的名称是main
第2个法的还回值类型是void
第3个法的名称是b
第3个法的还回值类型是void
第4个法的名称是wait
第4个法的还回值类型是void
第5个法的名称是wait
第5个法的还回值类型是void
第6个法的名称是wait
第6个法的还回值类型是void
第7个法的名称是equals
第7个法的还回值类型是boolean
第8个法的名称是toString
第8个法的还回值类型是class java.lang.String
第9个法的名称是hashCode
第9个法的还回值类型是int
第10个法的名称是getClass
第10个法的还回值类型是class java.lang.Class
第11个法的名称是notify
第11个法的还回值类型是void
第12个法的名称是notifyAll
第12个法的还回值类型是void