博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java复习总结——详细理解Java反射机制
阅读量:4354 次
发布时间:2019-06-07

本文共 8146 字,大约阅读时间需要 27 分钟。

1330447-20190415093551517-2116242619.png

反射是什么

反射的作用用一句简单的话来讲就是可以对代码进行操作的代码,这个特性经常在被用于创建JavaBean中,通常造轮子的人会用到这个特性,而应用程序员用到这个特性的场景则较少。

能够分析类能力的程序就叫做反射,简单来说就是可以对代码进行操作的代码。反射机制的功能极为强大,可以用来:

  • 在运行时分析类的能力
  • 在运行时查看对象
  • 实现通用的数组操作代码
  • 利用Method对象来实现方法

从获取Class类开始

在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。这个信息跟踪着每个对象所属的类。这个类的获取方式有以下三种:

  1. 使用Object类中的getClass()方法来返回一个Class类的实例

    User user;Class userClass  = user.getClass();
  2. 我们可以使用Class类的getName()方法来获取包含包名在内的类名。同样的,在已知这个名字的情况下,我们可以使用静态方法forName()获得类名对应的Class对象

Random generator = new Random();Class randomClass = generator.getClass();//className = "java.util.Random"String className = randomClass.getName();//第二种方式获取Class newRandomClass = Class.forName(className);
  1. 获得Class类对象的第三种方法很简单,如果T是任意的Java类型(或者void关键字),T.class将代表匹配的类对象。例如:
Class randomClass = Random.class;Class intClass = int.class;Class doubleClass = Double[].class;

如果我们想要创建一个类的实例,可以使用newInstance()方法来动态创建:

String s = "java.util.Random";Object m = Class.forName(s).newInstance();

构造函数的反射

获得构造函数的方法

//根据指定参数获得public构造器    Constructor getConstructor(Class[] params);    //获得public的所有构造器    Constructor[] getConstructors();    //根据指定参数获得public和非public的构造器    Constructor getDeclaredConstructor(Class[] params);    //获得public的所有构造器     Constructor[] getDeclaredConstructors();

看这些方法如何使用,先来个Student类供我们反射使用

public class Student {    private static String TAG = Student.class.getSimpleName();    public int age;    private String name;    public Student() {        age = 20;        name = "小明";    }    public Student(int age, String name) {        Log.e(TAG, "Student: " + "age " + age + " name " + name);    }    public void StudentA() {        Log.e(TAG, "StudentA: ");    }    public void StudentA(int age) {        Log.e(TAG, "StudentA: " + "age " + age);    }    public void StudentA(int age, String name) {        Log.e(TAG, "StudentA: " + "age " + age + " name " + name);    }}

利用反射分析类的能力

在java.lang.reflect包(反射库)中有三各类Field,MethodConstructor分别用于描述类的域,方法和构造器。这三个类都有一个叫做getName()的方法,用于返回项目的名称。Filed类有一个getType()方法,用于返回描述域所属类型的Class对象。Method和Constructor类有能够报告参数类型的方法,Method类还有一个可以报告返回类型的方法。

这三个类还有一个叫做getModifiers()的方法,它将返回一个整型数值,用不同的位开关描述public和static这样的修饰符使用情况。另外,还可以利用java.lang.reflect包中的Modifier类的静态方法分析getModifiers()返回的整型数值。例如,可以使用Modifier类中的isPublic()isPrivate()isFinal()判断方法或构造器是否是public,private或final。我们需要做的全部工作就是调用Modifier类的相应方法,并对返回的整数数值进行分析,另外,还可以利用Modifier.toString()方法将修饰符打印出来。

Class类中的getFields()getMethods()getConstructors()方法将分别返回类提供的public域、方法和构造器数组,其中包括超类的公有成员。Class类的getDeclareFieds()getDeclareMethods()getDeclareConstructors()方法将分别返回类中声明的全部域、方法和构造器,其中包括私有和受保护成员,但不包括超类的成员。

下面我们来编写一个程序可以做到输入类名,然后打印出这个类的全部信息的作用:

package com.reflect.test;import com.sun.org.apache.xpath.internal.operations.Mod;import java.io.File;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.util.Scanner;public class ReflectionTest {    public static void main(String[] args) {        String name;        if(args.length > 0){            name = args[0];        }else{            Scanner in = new Scanner(System.in);            System.out.println("请输入类名:");            name = in.next();        }        try{            Class c1 = Class.forName(name);            Class superclass = c1.getSuperclass();            String modifiers = Modifier.toString(c1.getModifiers());            if(modifiers.length() > 0){                System.out.println(modifiers + " ");            }            System.out.println("class"+name);            if(superclass != null && superclass != Object.class){                System.out.println("extends"+superclass.getName());            }            System.out.println("\n{\n");            printConstructors(c1);            System.out.println();            printMethods(c1);            System.out.println();            printFields(c1);            System.out.println("}");        }catch (ClassNotFoundException e){            e.printStackTrace();        }        System.exit(0);    }    private static void printFields(Class c1) {        Field[] fields = c1.getDeclaredFields();        for(Field field : fields){            Class type = field.getType();            String name = field.getName();            System.out.println("   ");            String modifiers = Modifier.toString(field.getModifiers());            if(modifiers.length() > 0){                System.out.println(modifiers + " ");            }            System.out.println(type.getName() + " " + name + ";");        }    }    private static void printMethods(Class c1) {        Method[] methods = c1.getDeclaredMethods();        for(Method method : methods){            Class returnType = method.getReturnType();            String name = method.getName();            System.out.println("  ");            String modifiers = Modifier.toString(method.getModifiers());            if(modifiers.length() > 0){                System.out.println(modifiers + " ");            }            System.out.println(returnType.getName()+" "+name+"(");            Class[] paramTypes = method.getParameterTypes();            for(int j = 0; j < paramTypes.length; j++){                if(j > 0){                    System.out.println(",");                }                System.out.println(paramTypes[j].getName());            }            System.out.println(");");        }    }    private static void printConstructors(Class c1) {        Constructor[] constructors = c1.getDeclaredConstructors();        for(Constructor constructor : constructors){            String name = constructor.getName();            System.out.println("  ");            String modifiers = Modifier.toString(constructor.getModifiers());            if(modifiers.length() > 0){                System.out.println(modifiers + " ");            }            System.out.println(name + "(");            Class[] paramTypes = constructor.getParameterTypes();            for(int j = 0; j < paramTypes.length; j++){                if(j > 0){                    System.out.println(",");                }                System.out.println(paramTypes[j].getName());            }            System.out.println(");");        }    }}

输入java.long.Double

回显:

请输入类名:java.lang.Doublepublic final Disconnected from the target VM, address: '127.0.0.1:51190', transport: 'socket'classjava.lang.Doubleextendsjava.lang.Number{  public java.lang.Double(double);  public java.lang.Double(java.lang.String);  public boolean equals(java.lang.Object);  public static java.lang.String toString(double);  public java.lang.String toString();  public int hashCode();  public static int hashCode(double);  public static double min(double,double);  public static double max(double,double);  public static native long doubleToRawLongBits(double);  public static long doubleToLongBits(double);  public static native double longBitsToDouble(long);  public volatile int compareTo(java.lang.Object);  public int compareTo(java.lang.Double);  public byte byteValue();  public short shortValue();  public int intValue();  public long longValue();  public float floatValue();  public double doubleValue();  public static java.lang.Double valueOf(java.lang.String);  public static java.lang.Double valueOf(double);  public static java.lang.String toHexString(double);  public static int compare(double,double);  public static boolean isNaN(double);  public boolean isNaN();  public static boolean isFinite(double);  public static boolean isInfinite(double);  public boolean isInfinite();  public static double sum(double,double);  public static double parseDouble(java.lang.String);   public static final double POSITIVE_INFINITY;   public static final double NEGATIVE_INFINITY;   public static final double NaN;   public static final double MAX_VALUE;   public static final double MIN_NORMAL;   public static final double MIN_VALUE;   public static final int MAX_EXPONENT;   public static final int MIN_EXPONENT;   public static final int SIZE;   public static final int BYTES;   public static final java.lang.Class TYPE;   private final double value;   private static final long serialVersionUID;}Process finished with exit code 0

1330447-20190415093754596-32480582.png

不积跬步无以至千里

思维导图

1330447-20190415093616621-1342861579.jpg

扩展阅读:

转载于:https://www.cnblogs.com/Tu9oh0st/p/10708859.html

你可能感兴趣的文章
PHP高级教程-Data
查看>>
POJ-1988-Cube_Stacking-并查集
查看>>
Qapp使用总结
查看>>
Delphi操作XML:函数详解(一)
查看>>
网盘搜索网站汇总
查看>>
第十六章 数组
查看>>
又是一年毕业季
查看>>
ThinkPHP 3.2.3 Widget 扩展的使用
查看>>
(转)同步异步,阻塞非阻塞 和nginx的IO模型
查看>>
(转) CentOS7.4 + MySQL8.0 + Git + Gogs搭建
查看>>
简单选项卡加圆角
查看>>
ZOJ3741 状压DP Eternal Reality
查看>>
POJ 1741 Tree(树的分治)
查看>>
soritong MP3播放器缓冲区溢出漏洞分析
查看>>
how to istall virtualbox on centos
查看>>
PowerDesigner生成的ORACLE 建表脚本中去掉对象的双引号,设置大、小写
查看>>
LA 3902 UVA 1267 - Network
查看>>
docker 学习(1)
查看>>
递归--任意字符全排列(第二次写)
查看>>
17.10.24 数据最水的一次考试
查看>>