Java 查看类图工具(手写小工具,不用引任何包和插件)

我们在进行源码学习的时候,经常要查看某个类的类图,虽然 IDEA 有自带的类图显示,但那也只是付费版,社区版的并不支持,而 Eclipse 是压根儿就没有,其实功能挺简单的,于是就自己写了一个查看类图小工具给分享给大家。 

先放效果图:

 从这效果图中,我们就很清晰的看到,ArrayList 的父类是 AbstractList,父接口有 List、RandomAccess、Cloneable、Serializable。而父类 AbstractList 的父类是 AbstractCollection,它实现的接口同样有List,以此类推。

 当然,我们用起来也比较简单,只需要调用工具类 showDiagram() 方法,把要查看的类传进去即可。

DiagramUtils.showDiagram(ArrayList.class, true);

如果你想要查看接口或类的简名,只需要把第二个参数改为 false 即可(效果图如下):

 【源码展示】

package com.test.inherited;

import java.util.ArrayList;
import java.util.List;

/**
 * 类图查看工具类
 *
 * @author zyq
 * @since 2021/08/18
 */
public class DiagramUtils {

    private static List<String> list = new ArrayList<>();

    public static void main(String[] args) {
        DiagramUtils.showDiagram(ArrayList.class, false);
    }

    /**
     * 打印类或接口的类图关系
     *
     * @param clazz          类或接口
     * @param isShowFullName 是否显示类全名,true-显示类全名,false-显示简名
     */
    public static void showDiagram(Class clazz, boolean isShowFullName) {
        if (clazz == null) {
            System.out.println("你没有传参");
        }
        Node node = getSupper(clazz, isShowFullName);
        if (node != null) {
            print(node, 0);
        }
        handleAll();
        for (int i = list.size() - 1; i >= 0; i--) {
            System.out.println(list.get(i).substring(4));
        }
    }

    private static void handleAll() {
        // 获取最大的层级
        int max = 1;
        for (int i = list.size() - 1; i > 0; i--) {
            int level = getLevel(list.get(i));
            if (max < level) {
                max = level;
            }
        }
        // 循环处理每层树状
        for (int i = max; i > 0; i--) {
            handle(i);
        }
    }

    private static void handle(int level) {
        // 获取该层次的所有序号
        List<Integer> rowList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if (level == getLevel(list.get(i))) {
                rowList.add(i);
            }
        }
        if (rowList.size() <= 1) {
            return;
        }
        // 判断两个依次同层级的是否为连续
        int i = 0;
        while (i < rowList.size() - 1) {
            int num1 = rowList.get(i);
            int num2 = rowList.get(i + 1);
            i++;
            // 相邻的直接略过
            if (num1 + 1 == num2) {
                continue;
            }
            // 判断两行之间是否有阻碍,没有阻碍才连续
            boolean isOk = true;
            int levelIndex = level * 4;
            for (int j = num1; j < num2; j++) {
                String s = list.get(j);
                if (s.length() > levelIndex) {
                    char c = s.charAt(levelIndex);
                    if (c != ' ' && c != '|') {
                        isOk = false;
                    }
                }
            }
            if (isOk) {
                for (int j = num1; j < num2; j++) {
                    list.set(j, setLevel(list.get(j), level));
                }
            }
        }
    }

    private static String setLevel(String s, int level) {
        int levelIndex = level * 4;
        if (s.length() > levelIndex) {
            char[] chars = s.toCharArray();
            chars[levelIndex] = '|';
            return new String(chars);
        } else {
            int diff = levelIndex - s.length();
            for (int i = 0; i < diff - 1; i++) {
                s += " ";
            }
            return  s + "|";
        }
    }

    private static int getLevel(String s) {
        String start = "|---";
        int level = 0;
        while (level < 100) {
            level ++;
            start = "    " + start;
            if (s.startsWith(start)) {
                break;
            }
        }
        return level;
    }


    private static void print(Node node, int level) {
        String lineBlank = "";
        for (int i = level; i > 0; i--) {
            lineBlank += "    ";
        }
        String s = lineBlank + "|---" + node.getName() + " " + node.getType();
        list.add(s);
        List<Node> superList = node.getSuperList();
        if (superList.size() > 0) {
            for (Node each : superList) {
                print(each, level + 1);
            }
        }
    }

    private static Node getSupper(Class clazz, boolean isShowFullName) {
        Node node = new Node();
        if (clazz.isInterface()) {
            node.setType("(I)");
        } else {
            node.setType("(C)");
        }
        node.setName(getClassName(clazz, isShowFullName));
        Class superclass = clazz.getSuperclass();
        if (superclass != null) {
            node.getSuperList().add(getSupper(superclass, isShowFullName));
        }
        Class[] interfaces = clazz.getInterfaces();
        if (interfaces != null && interfaces.length > 0) {
            for (Class anInterface : interfaces) {
                node.getSuperList().add(getSupper(anInterface, isShowFullName));
            }
        }
        return node;
    }


    private static String getClassName(Class clazz, boolean isShowFullName) {
        return isShowFullName ? clazz.getName() : clazz.getSimpleName();
    }

    private static class Node {
        private String name;
        private String type;
        private List<Node> superList = new ArrayList<>();

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public List<Node> getSuperList() {
            return superList;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/sunnyzyq/article/details/119784763