JAVA反射
反射作用:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;
这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
一、得到反射的三种方法?
1、类.class;
2、对象.getClass();
3、class.formName();
二、一个类里都有什么?
类名、类修饰符、包信息、父类、实现的接口、属性、方法、构造器(构造方法)、注解多部分组成。
三、属性有几部分组成?
修饰符、类型、属性名、属性值四部分组成。
四、方法有几部分组成?
修饰符、返回类型、方法名、参数列表、方法体、返回值
五、构造器几部分组成?
修饰符、构造器名称(类名)、参数列表、方法体
A、对类的包名进行反射
Class clazz = 类.class;
Package packag = clazz.getPackage();
System.out.println(packag); //得到 package + 完全限定包名
System.out.println(packag.getName()); //得到完全限定包名
B、对类名进行反射
Class clazz = 类.class;
String className = clazz.getName(); //完全限定类名(包括包名)
String className = clazz.getCanonicaName(); //完全限定类名(包括包名)
String className = clazz.getSimpleName(); //获取不含包名的类名
C、对类修饰符进行反射
Class clazz = 类.class;
int modifieers = clazz.getModifiers(); //得到类的修饰符是数字型
System.out.println(Modifier.toString(modifieers)); // Modifier.toString(); 该方法用来将数字型转换成修饰符
可以使用java.lang.reflect.Modifier类中的以下方法来检验修饰符:
Modifier.isAbstract(int modifiers)
Modifier.isFinal(int modifiers)
Modifier.isInterface(int modifiers)
Modifier.isNative(int modifiers)
Modifier.isPrivate(int modifiers)
Modifier.isProtected(int modifiers)
Modifier.isPublic(int modifiers)
Modifier.isStatic(int modifiers)
Modifier.isStrict(int modifiers)
Modifier.isSynchronized(int modifiers)
Modifier.isTransient(int modifiers)
Modifier.isVolatile(int modifiers)
返回的是布尔型,用来判断真假!
D、对父类进行反射
Class clazz = Student.class;
Class superclass = clazz.getSuperclass(); //得到父类的完权限定名
String simpleName = clazz.getSuperclass().getSimpleName(); //得到不含包名的父类名
E、对接口进行反射
Class clazz = Student.class;
Class[] interfaces = clazz.getInterfaces();
for(i = 0; i < interfaces.length; i++){
System.out.println(interface[i]); //得到 interface + 完全限定名
System.out.println(interface[i].getName()); //得到接口的完全限定名
System.out.println(interface[i].getSimpleName()); //得到该类所实现的接口名
}
F、对属性进行反射
Class clazz = 类.Class;
Field[] fields = clazz.getFields(); //该方法功能得到本类中的所有公共属性,包括所有继承的公共属性
Field[] fields = clazz.getDeclaredFields(); //该方法用于得到本类中所有的属性(一般使用较多)
G、对属性修饰符进行反射
Class clazz = 类.Class;
Field[] fields = clazz.getDeclaredFields();
for(Field field: fields){
//遍历输出属性名
sysotem.out.println(field.getName()); //field.getName()该方法用于得到属性名
//遍历输出属性的修饰符用数字进行表示
sysotem.out.println(field.getModifiers()); //field.getModifiers()用于获取所有用数字表示的修饰符
//遍历输出属性的修饰符
sysotem.out.println("修饰符:"+Modifier.toString(field.getModifiers())); //Modifier.toString()
方法用来将数字表示的修饰符,转换成真正的修饰符。toString()中参数为int类型。
}
数字对应的修饰符为:
0 什么也没有(默认)
1 public
2 private
4 protected
8 static
16 final
32 synchronized
64 volatile
128 transient
256 native
512 interface
1024 abstract
2048 strictfp
H、对属性的类型进行反射
Class clazz = 类.Class;
Field[] fields = clazz.getDeclaredFields(); //该方法用于得到本类中所有的属性(一般使用较多)
for(Field field: fields){
system.out.println(field.getType());//输出 class + 类型的完全权限定名
system.out.println(field.getType().getSuperclass());//输出 class + 属性类型的父类,完全权限定名
system.out.println(field.getType().getSuperclass());//输出 属性类型的父类
system.out.println("类型:"+field.getType().getSimpleName());//遍历输出属性的类型
}
I、对属性的值进行反射
注意:在对属性值进行反射时需要进行try{}catch{}一下, field.get(obj)只能接收对象(obj)
public class Student{
//不同修饰符和里类型的属性
private String id;
public Integer count;
String name;
protected int age;
//不同修饰符及返回类型的方法
publice void eat(){
}
protected String sleep(){
return "hello";
}
int play(){
return 2;
}
private boolean show(int age, String name, boolean flag){
age = age +1;
return true;
}
// 不同构造函数
public Student(){
}
public Student(String name,Integer count){
}
}
Student stu = new Student();
Class clazz = stu.getClass();
Field[] fields = clazz.getDeclaredFields(); //该方法用于得到本类中所有的属性(一般使用较多)
for(Field field: fields){
//filed.setAccessible(true);该方法接收boolean类型。用来将本类中private修饰的属性的值显示出来
system.out.println(field.get(sut)); //field.get(sut)该方法用于得到除private修饰符修饰的所有值,private修饰的属性会报错。要想得到private的属性值,可以使用field.setAccessible()方法。
//注意 field.get(sut)方法的参数需要是对象类型。
}
J、对方法进行反射
Class clazz = Studet.class; //对Student类中的方法进行反射
Methd[] methods = clazz.getMethods(); //clazz.getMethods();该方法功能得到本类中的所有公共方法,包括所有继承的公共方法
//如果Studet类中没有方法,则将父类(Object)中的public修饰的方法名显示出来。
Methd[] methods = clazz.getDeclaredlMethods(); //clazz.getDeclaredlMethods();该方法用于得到本类中所有的方法(一般使用较多)
K、对方法的修饰符进行反射
Student student = new Student();
Class clazz = student.getClass(); //对Student类中的方法进行反射
try{
//Methd[] methods = clazz.getMethods();
Methd[] methods = clazz.getDeclaredlMethods();
for(Method method : methods) {
system.out.println(method.getModifiers()); //method.getModifiers()用于获取所有用数字表示的修饰符
//Modifier.toString(); 方法用来将数字表示的修饰符,转换成真正的修饰符。toString()中参数为int类型。
system.out.println(Modifier.toString(method.getModifiers()));
}
}catch(Exception e){
e.printstackTrace();
}
L、对方法的返回类型行反射
Student student = new Student();
Class clazz = student.getClass(); //对Student类中的方法进行反射
try{
//Methd[] methods = clazz.getMethods();
Methd[] methods = clazz.getDeclaredlMethods();
for(Method method : methods) {
system.out.println(method.getReturnType()); //method.getReturnType()用于获取方法的返回类型+该类型包名
system.out.println(method.getReturnType().getSimpleName()); //getSimpleName();得到方法的返回类型没有包名
}
}catch(Exception e){
e.printstackTrace();
}
M、对方法的方法名进行反射
Student student = new Student();
Class clazz = student.getClass(); //对Student类中的方法进行反射
try{
Methd[] methods = clazz.getDeclaredlMethods();
for(Method method : methods) {
system.out.println(method.getName()); //method.getName()方法用来得到方法的名字,
}
}catch(Exception e){
e.printstackTrace();
}
N、对方法的参数列表进行反射
Student student = new Student();
Class clazz = student.getClass(); //对Student类中的方法进行反射
try{
Methd[] methods = clazz.getDeclaredlMethods();
for(Method method : methods) {
Class<?>[] parameterTypes = method.getParameterTypes(); //得到方法的参数列表是一个Class<?>[] 数组
system.out.println(Arrays.toString(parameterTypes)); //Arrays.toString();该方法用来将数组转换成字符串
}
}catch(Exception e){
e.printstackTrace();
}
O、对方法的返回值进行反射
//注意方法的方法体是无法进行反射的。
/**
*由于每一个方法的参数个数和参数类型不一样,
*返回值也不一样,所以我们需要得到每个方法的参数进行判断,
*并方法名、对象、方法的参数都是必填项。
*/
Student student = new Student();
Class clazz = student.getClass();
Method[] methods = clazz.getDeclaredMethods();
for(Method method : methods){
if(method.getName().equals("方法名")){
//method.invoke(object,参数1,参数2,参数n) 该方法用来获取方法的返回值。
System.out.println(method.invoke(对象,方法的参数…);
}
}
//方法和参数进行判断若不对会报错:java.lang.IllegalArgumentException: wrong number of arguments
P、对构造函数进行反射
Class clazz = Student.class;
Constructor[] constructors = aClass.getConstructors(); //得到所有公共的构造器,因为父类中的构造器无法继承,所以不包括父类中公共构造器。
Constructor constructors = aClass.getDeclaredConstructors(); //得到本类中对应的构造器。
try {
Constructor constructor = clazz.getDeclaredConstructor(int.class,String.class); //获取Student类中有2个参数的构造器
//方法constructor.newInstance(1,"a");用来实例化 调用该构造器,并将参数值写入。
Object instance = constructor.newInstance(1,"a");
} catch (Exception e) {
e.printStackTrace();
}
Q、对构造器修饰符、名称、参数列表进行反射
Class clazz = Student.class;
Constructor[] constructors = clazz.getDeclaredConstructors();
for(Constructor constructor:concstructors) {
System.out.println("修饰符"+Modifier.toString(constructor.getModifiers())); //得到构造器修饰符
System.out.println("名称:"+constructor.getName()); //得到构造器的名称
//constructor.getParameterTypes();方法得到的是一个 Class<?>[]
System.out.println(constructor.getParameterTypes()); //输出的是一个数组的地址
System.out.println("参数列表"+Arrays.toString(constructor.getParameterTypes())); //Arrays.toString();输出的是数组转换的字符串
}
注意:以上所有操作都是在main()方法中执行。
温馨提示:反射中还有注解、泛型等,由于时间的关系,我就先写到这里,争取下次补全。