Java viewing class diagram tool (handwritten small tool, no need to cite any packages and plug-ins)

When we study the source code, we often have to check the class diagram of a certain class. Although IDEA has its own class diagram display, it is only the paid version, the community version does not support it, and Eclipse does not have it at all. In fact, the function is quite simple, so I wrote a small tool for viewing class diagrams to share with you. 

Put the renderings first:

 From this rendering, we can clearly see that the parent class of ArrayList is AbstractList, and the parent interface includes List, RandomAccess, Cloneable, and Serializable. The parent class of AbstractList is AbstractCollection, and the interface it implements also has List, and so on.

 Of course, it is also relatively simple for us to use. We only need to call the showDiagram() method of the tool class and pass in the class to be viewed.

DiagramUtils.showDiagram(ArrayList.class, true);

If you want to view the short name of the interface or class, just change the second parameter to false (the effect is as follows):

 

 [Source code display]

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;
        }
    }
}

Guess you like

Origin blog.csdn.net/sunnyzyq/article/details/119784763