用反射打印一个类的全部信息(分析)

这是《Java核心技术 卷I》用反射打印一个类的全部信息的全部代码,后续将会拆解这些代码

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) {

        // read class name from command line args or user input
        String name;
        if (args.length > 0)
            name = args[0];
        else {
            Scanner in = new Scanner(System.in);
            System.out.println("Enter class name (e.g. java.util.Date)");
            name = in.next();
        }

        try {// print class name and super class name(if !=Object)
            Class cl = Class.forName(name);
            Class supercl = cl.getSuperclass();
            String modifiers = Modifier.toString(cl.getModifiers());
            if (modifiers.length() > 0)
                System.out.print(modifiers + " ");
            System.out.print("class " + name);
            if (supercl != null && supercl != Object.class)
                System.out.print(" extends " + supercl.getName());

            System.out.print("\n{\n");
            printConstructors(cl);
            System.out.println();
            printMethods(cl);
            System.out.println();
            printFields(cl);
            System.out.println("}");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.exit(0);
    }

    // prints all constructor of a class
    public static void printConstructors(Class cl) {

        Constructor[] constructor = cl.getDeclaredConstructors();

        for (Constructor c : constructor) {// 构造器由 “修饰符 + 名字 + 参数 ” 组成
            String modifiers = Modifier.toString(c.getModifiers());
            String name = c.getName();
            System.out.println("Constructors:");
            if (modifiers.length() > 0)
                System.out.print(modifiers + " ");
            System.out.print(name + "(");

            // print parameter types
            Class[] paramTypes = c.getParameterTypes();
            for (int i = 0; i < paramTypes.length; i++) {
                if (i > 0)
                    System.out.print(",");
                System.out.print(paramTypes[i].getName());
            }
            System.out.print(");");
            System.out.println();
            System.out.println();
        }

    }

    // print all methods of a class
    public static void printMethods(Class cl) {

        Method[] methods = cl.getDeclaredMethods();

        for (Method m : methods) {
            String modifier = Modifier.toString(m.getModifiers());
            Class retType = m.getReturnType();
            String name = m.getName();
            System.out.println("Methods:");

            // print modifiers,returnType and method name
            if (modifier.length() > 0)
                System.out.print(modifier + " ");
            System.out.print(retType + " " + name + "(");

            // print parameter types
            Class[] parameters = m.getParameterTypes();
            for (int i = 0; i < parameters.length; i++) {
                if (i > 0)
                    System.out.print(",");
                System.out.print(parameters[i].getName());
            }
            System.out.println(")");
            System.out.println();
        }

    }

    // print all fields of a class
    public static void printFields(Class cl) {
        Field[] fields = cl.getDeclaredFields();

        for (Field f : fields) {
            Class type = f.getType();
            String name = f.getName();
            System.out.println("Fields:");
            String modifiers = Modifier.toString(f.getModifiers());
            if (modifiers.length() > 0)
                System.out.print(modifiers + " ");
            System.out.print(type.getName() + " " + name + ";");
            System.out.println();
        }
    }

}

首先,类的信息有类名,有没有父类,有成员变量,有构造方法,有成员方法。而 ,

成员变量 = 修饰符 + 域类型 + 名字 (private String name)

构造方法 = 修饰符 + 名字 + 参数(public Student(String name, int age))参数的括号,逗号是排版问题了,正是因为这个排版问题,输出参数的时候用 foreach 语句比较难排版,所以用了for语句。

成员方法 = 修饰符 + 返回值 + 名字 + 参数

其实处理这些信息操作基本上是一样的
比如:xxx是一个field[ ],Constructor[ ] 或者Method[ ] 的对象,在用增强for遍历他们的时候(假设遍历的符号x),

修饰符 : String modifiers = Mofier.toString(x.getModifiers);
x.getModifiers返回一个 int 的数值,而ModiMofier.toString这个静态方法可以根据这个数值返回修饰符的信息。因为修饰符是可能没有的,所以要用if(modifiers.length() > 0)来判断有没有修饰符,有就打印,没有就不打印

名字 : String name = x.getName();
Field,Method,Constructor 这三个类都有getName方法,用来返回项目名称。
另外提的是Clas类中也有一个getName方法,这个方法返回的是类的名字。

参数 :
Class[] paramTypes = c.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0)
System.out.print(",");
System.out.print(paramTypes[i].getName());

paramTypes是Class[ ]的数组,循环输出里面每一个“类”的名字,就用到了Class类的getName方法了

成员/构造)方法参数,成员类型,方法返回类型,这三个都是返回一个Class对象(参数是对象数组),想要把他们打印出来,就要用 getName来返回他们的名字

下面看打印构造方法的printConstructors方法

// prints all constructor of a class
    public static void printConstructors(Class cl) {

        Constructor[] constructor = cl.getDeclaredConstructors();

        for (Constructor c : constructor) {// 构造器由 “修饰符 + 名字 + 参数 ” 组成
            String modifiers = Modifier.toString(c.getModifiers());
            String name = c.getName();
            System.out.println("Constructors:");
            if (modifiers.length() > 0)
                System.out.print(modifiers + " ");
            System.out.print(name + "(");

            // print parameter types
            Class[] paramTypes = c.getParameterTypes();
            for (int i = 0; i < paramTypes.length; i++) {
                if (i > 0)
                    System.out.print(",");
                System.out.print(paramTypes[i].getName());
            }
            System.out.print(");");
            System.out.println();
            System.out.println();
        }

    }

1.无论是成员变量,构造器,还是成员方法,都是可以用private修饰的,所以定义他们的对象的时候一定要用getDeclaredXXXX(访问全部方法/成员)

2.Constructor[ ] 接收了一堆构造器方法,要遍历它,最简单的就是用增强for

3.因为增强for遍历的时候,需要输出这个构造器的信息,所以在每个构造器的名字,修饰符,参数,应该在增强for里面创建。而参数正好又是Class[ ] 接收的一个数组,于是又可以使用for语句遍历,不用增强for是因为增强for很难排版到我们想要的格式

一样的来看打印成员方法的printMethods方法

public static void printMethods(Class cl) {

        Method[] methods = cl.getDeclaredMethods();

        for (Method m : methods) {
            String modifier = Modifier.toString(m.getModifiers());
            Class retType = m.getReturnType();
            String name = m.getName();
            System.out.println("Methods:");

            // print modifiers,returnType and method name
            if (modifier.length() > 0)
                System.out.print(modifier + " ");
            System.out.print(retType + " " + name + "(");

            // print parameter types
            Class[] parameters = m.getParameterTypes();
            for (int i = 0; i < parameters.length; i++) {
                if (i > 0)
                    System.out.print(",");
                System.out.print(parameters[i].getName());
            }
            System.out.println(")");
            System.out.println();
        }

    }

1.定义Mehod[ ] 对象并且遍历他
2.各要素的创建,排版
3.留意的地方:修饰符打印要通过if (modifier.length() > 0)这条语句判断,因为可能存在没有修饰符的情况,不能瞎打印
不要忘了参数 parameters 是一个数组,每一个方法的参数都放在里面,遍历他们并通过parameters[i].getName()来获取他们的名字

下面是打印成员变量的printFields方法

public static void printFields(Class cl) {
        Field[] fields = cl.getDeclaredFields();

        for (Field f : fields) {
            Class type = f.getType();
            String name = f.getName();
            System.out.println("Fields:");
            String modifiers = Modifier.toString(f.getModifiers());
            if (modifiers.length() > 0)
                System.out.print(modifiers + " ");
            System.out.print(type.getName() + " " + name + ";");
            System.out.println();
        }
    }

1.和成员方法不同,成员方法用getReturnType()返回一个返回类型成员变量的域类型是通过getType()返回的,一样的是返回一个Class对象,所以也是要用getName来获取它的类型名字

最后是main方法

public static void main(String[] args) {

        // read class name from command line args or user input
        String name;
        if (args.length > 0)
            name = args[0];
        else {
            Scanner in = new Scanner(System.in);
            System.out.println("Enter class name (e.g. java.util.Date)");
            name = in.next();
        }

        try {// print class name and super class name(if !=Object)
            Class cl = Class.forName(name);
            Class supercl = cl.getSuperclass();
            String modifiers = Modifier.toString(cl.getModifiers());
            if (modifiers.length() > 0)
                System.out.print(modifiers + " ");
            System.out.print("class " + name);
            if (supercl != null && supercl != Object.class)
                System.out.print(" extends " + supercl.getName());

            System.out.print("\n{\n");
            printConstructors(cl);
            System.out.println();
            printMethods(cl);
            System.out.println();
            printFields(cl);
            System.out.println("}");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.exit(0);
    }

1.从控制台输入或者用户输入”包名 + 类名“来创建一个字符串,用于后面建立Class对象
2.查找它有没有父类,判断条件,这个父类不为空,而且不是Object类,Object类不算,他是所有类的父类
3.打印这个类的名字等信息(修饰符,类名,继承谁),类不一定都是public,所以依旧要判断有没有修饰符就是有修饰符都要想到判断吧有Class要想到用getName获取他们的名字

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android开发,如果想将泛型作为字符串打印出来,可以使用Java反射机制来实现。以下是一种可能的实现方式。 1. 首先,定义一个泛型或方法,例如: ```java public class GenericClass<T> { // ... // 定义一些泛型方法或成员变量 // ... } ``` 2. 在Android,使用反射机制获取泛型的型,并将其转换为字符串。可以使用如下代码: ```java GenericClass<Integer> genericClass = new GenericClass<>(); Type genericType = genericClass.getClass().getGenericSuperclass(); if (genericType instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) genericType; Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); for (Type type : actualTypeArguments) { String typeName = type.toString(); Log.d(TAG, "泛型型:" + typeName); } } ``` 上述代码,首先创建一个泛型对象`genericClass`,然后通过`getClass()`获取Class对象,接着使用`getGenericSuperclass()`获取泛型的型`genericType`。 3. 判断泛型型是否是参数化型`ParameterizedType`,如果是,通过调用`getActualTypeArguments()`方法获取泛型参数型,并将其转换为字符串,最后通过`Log.d()`或其他方式打印出来。 需要注意的是,以上代码仅适用于泛型,如果要适用于泛型方法,可以使用`Method`的`getGenericReturnType()`等方法获取相关信息。 总结:通过以上步骤,我们可以将Android的泛型作为字符串打印出来,并在开发过程对其进行调试和分析

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值