⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debug.java

📁 培训考试系统代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package com.huawei.icd30.agt.util;

import java.io.*;
import java.util.*;
import java.text.*;
import java.lang.reflect.*;

/**
 * 调试工具类。该类提供两个主要的静态方法:
 * <OL><LI>myAssert(boolean 条件);断言,用来确保本应成立的条件确实成立,防止
 * 错误扩散。
 * <LI>dump(任何数据类型,递归深度);输出一个变量的内容,后一个参数可省,
 * 缺省值为3。该方法可以输出任何数据类型的变量的内容,包括基本数据类型、数
 * 组和对象。对一些常用对象,如Vector等,有专门的输出格式。其他对象将输出其
 * 成员变量,包括私有变量和静态变量。输出过程会一直递归,递归层次由deep参数
 * 来控制,如果递归层次超过限制值,则直接输出toString()的内容,如果递归出现
 * 循环,则在发现重复引用处停止递归。输出信息除对象的内容外还包括输出时间、
 * 调用dump函数的代码所在源文件,行号,若是对象还包括该对象的地址(注:虚拟
 * 机内部编址,非物理地址,可用来判断两个变量是否是同一个对象的引用)。</OL>
 * 该类未引用其他类,可单独编译。该类只供调试使用,未做性能优化。
 * @author websms
 * @version 1.0
 */
public class Debug {

  /**
   * 构造方法私有,禁止实例化。
   */
  private Debug() {}

  /**
   * 断言,condition条件一定成立,否则断言失败,断言失败时抛出异常,断言使用在
   * 判断在任何情况下都不应该出现的错误,如果断言失败表示程序有BUG,在系统发布
   * 前必须保证所有断言都永远成立。不应用断言来做为程序运行期间出错处理的手段。
   * @param condition 断言条件。
   * @param message 断言失败时输出的消息。
   */
  public static final void myAssert(boolean condition) {
    if(!condition) throw new AssertFailed();
  }

//---------------dump方法,用法:Debug.dump(<任意数据类型>);-------------------

  /** dump分层结构时每级缩进固定为4个空格。*/
  private static String indentString = "    ";

  /** 当前系统行分隔符。*/
  private static final String lineSeparator =
      System.getProperty("line.separator");

  /**
   * dump()方法输出数据的目的流,缺省指向标准错误输出设备上。
   * 可以通过setDumpStream(OutputStream)方法修改,也可以直接对该对象赋值。
   */
  public static PrintWriter out = new PrintWriter(System.out);

  /**
   * 设置dump信息的输出目的流,此后调用dump都将输出到该流中。
   * @param os 输出流。
   */
  public static void setDumpStream(OutputStream os) {
    out = new PrintWriter(os);
  }

  /**
   * 设置dump信息的输出目的流,此后调用dump都将输出到该流中。
   * @param w 一个Writer对象。
   */
  public static void setDumpStream(Writer w) {
    out = new PrintWriter(w);
  }

  /**
   * 设置递归缩进时填补的字符串。缺省为4个空格。
   * @param indent 缩进时填补的字符串。
   */
  public static void setDumpIndent(String indent) {
    indentString = indent;
  }

  /**
   * 获取递归缩进时填补的字符串。
   * @return 缩进时填补的字符串。
   */
  public static String getDumpIndent() {
    return indentString;
  }

  /**
   * 输出空行。
   */
  public static final void dump() {
    out.println(dumpHead());
    out.flush();
  }

  /**
   * 输出整数。
   * @param i 要输出的整数。
   */
  public static final void dump(int i) {
    out.println(dumpHead() + i);
    out.flush();
  }

  /**
   * 输出长整数。
   * @param l 要输出的长整数。
   */
  public static final void dump(long l) {
    out.println(dumpHead() + l);
    out.flush();
  }

  /**
   * 输出浮点数。
   * @param f 要输出的浮点数。
   */
  public static final void dump(float f) {
    out.println(dumpHead() + f);
    out.flush();
  }

  /**
   * 输出双精度浮点数。
   * @param d 要输出的双精度浮点数。
   */
  public static final void dump(double d) {
    out.println(dumpHead() + d);
    out.flush();
  }

  /**
   * 输出布尔值。
   * @param d 要输出的布尔值。
   */
  public static final void dump(boolean b) {
    out.println(dumpHead() + b);
    out.flush();
  }

  /**
   * 输出一个字符ch。
   * @param ch 要输出的字符。
   */
  public static final void dump(char ch) {
    out.println(dumpHead() + ch);
    out.flush();
  }

  /**
   * 输出字节数组中的一部分数据。
   * @param data 待输出数据所在字节数组。
   * @param offset 待输出数据开始位置。
   * @param length 待输出数据长度。
   */
  public static final void dump(byte[] data,int offset,int length) {
    dump(dumpHead(),data,offset,length);
  }

  /**
   * 输出字节数组完整内容。
   * @param data 待输出字节数组。
   */
  public static final void dump(byte[] data){
    dump(dumpHead(),data);
  }

  /**
   * 输出一个对象(可以是任何对象、对象数组)
   * @param obj 要输出的对象。
   */
  public static final void dump(Object obj) {
    dump(dumpHead(),3,new Vector(),obj);
  }

  /**
   * 输出一个对象(可以是任何对象、对象数组),带前缀
   * @param obj 要输出的对象。
   * @param prefix 输出信息的前缀。
   */
  public static final void dump(Object obj,String prefix) {
    dump(prefix + dumpHead(),3,new Vector(),obj);
  }

  /**
   * 输出一个对象(可以是任何对象、对象数组)
   * @param obj 要输出的对象。
   * @param depth 递归深度。
   */
  public static final void dump(Object obj,int depth) {
    dump(dumpHead(),depth,new Vector(),obj);
  }

  //------------------------ 以下是私有方法,不对外开放 -----------------------

  /**
   * 输出向量内容。
   * @param prefix 输出前缀。
   * @param depth 最大dump深度。
   * @param v 输出的向量。
   */
  private static final void dump(String prefix,int depth,Vector checkCircuit,Vector v){
    if (v==null) {
      dump(prefix,"null");
      return;
    }
    dumpBegin(prefix,checkCircuit,v);
    for (int i=0;i<v.size();i++) {
      Object item = v.elementAt(i);
      StringBuffer itemPrefix = new StringBuffer();
      itemPrefix.append(indent(prefix));
      itemPrefix.append('[');
      itemPrefix.append(i);
      itemPrefix.append("] ");
      itemPrefix.append(formatClassName(item.getClass(),item));
      itemPrefix.append(" @");
      itemPrefix.append(System.identityHashCode(item));
      dump(itemPrefix.toString(),depth,checkCircuit,item);
    }
    dumpEnd(prefix,checkCircuit,v);
  }

  /**
   * 输出Servlet的request请求中的参数。
   * @param prefix 输出前缀。
   * @param request 要输出的请求。
   */
  private static final void dumpServletRequest(String prefix,Object request) {
    try {
      if (request == null) {
        dump(prefix,"null");
        return;
      }
      dumpBegin(prefix,new Vector(),request);
      Class c = request.getClass();
      Method m1 = null;
      m1 = c.getMethod("getParameterNames",new Class[]{});

      for (Enumeration e = (Enumeration) m1.invoke(request,new Object[]{});
           e.hasMoreElements();) {
        String name = e.nextElement().toString();
        Method m2 = c.getMethod("getParameterValues",new Class[]{String.class});
        String[] values = (String[]) m2.invoke(request,new Object[]{name});
        StringBuffer sb = new StringBuffer();
        for (int i=0; i<values.length; i++) {
          sb.append(values[i]);
          if (i!=values.length -1) {
            sb.append(" ; ");
          }
        }
        dump(indent(prefix),name + " = " + sb);
      }
      dumpEnd(prefix,new Vector(),request);
    } catch (Exception ex) {
      ex.printStackTrace(out);
    }
  }

  /**
   * 输出符合Enumeration接口的对象的内容
   * @param prefix 输出前缀。
   * @param depth 最大dump深度。
   * @param e 输出的枚举对象。
   */
  private static final void dump(String prefix,int depth,Vector checkCircuit,Enumeration e){
    if (e==null) {
      dump(prefix,"null");
      return;
    }
    dumpBegin(prefix,checkCircuit,e);
    int i=0;
    while (e.hasMoreElements()) {
      dump(indent(prefix) + '[' + (i++) + "] ",depth,checkCircuit,e.nextElement());
    }
    dumpEnd(prefix,checkCircuit,e);
  }

  /**
   * 输出异常信息。
   * @param prefix 输出前缀。
   * @param t 待输出的异常。
   */
  private static final void dump (String prefix,Throwable t) {
    if (t==null) {
      dump(prefix,"null");
      return;
    }
    dumpBegin(prefix,new Vector(),t);
    t.printStackTrace(out);
    dumpEnd(prefix,new Vector(),t);
  }

  /**
   * 输出字节数组片段。
   * @param prefix 输出前缀。
   * @param data 输出的字节数组。
   * @param offset 输出开始的偏移地址。
   * @param length 长度。
   */
  private static final void dump(String prefix,byte[]data,int offset,int length) {
    if (data ==null) {
      dump(prefix,"null");
      return;
    }
    if ( offset<0||data.length<offset+length) {
      dump(prefix,"IndexOutOfBounds:data.length=" + data.length + " offset=" +
                                           offset + " length=" + length);
      return;
    }
    dumpBegin(prefix,new Vector(),data);
    int end = offset + length;
    dump(indent(prefix),"[HEX]  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f | 0123456789abcdef");
    dump(indent(prefix),"------------------------------------------------------------------------");
    for (int i=offset; i<end; i+=16) {
      byte[] row = new byte[] { 0x30,0x30,0x30,0x30,0x3A,0x20,
        0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,
        0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,
        0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,
        0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0x20,
        0x7C,0x20,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,
        0x2E,0x2E,0x2E,0x2E,0x2E,0x2E
      };
      setHex(row,3,i);
      for (int j=i; j<i+16; j++) {
        if (j<end) {
          int b = data[j];
          if (b<0) b += 256;
          setHex(row,7+(j-i)*3,b);
          if (b>=32 && b<127) {
            row[56+j-i]=(byte)b;
          }
        }
        else {
          row[6+(j-i)*3]=(byte)' ';
          row[7+(j-i)*3]=(byte)' ';
          row[56+(j-i)] =(byte)' ';
        }
      }
      dump(indent(prefix),new String(row));
    }
    dumpEnd(prefix,new Vector(),data);
  }

  /**
   * 输出字节数组完整内容。
   * @param prefix 输出前缀
   * @param b 输出的字节数组。
   */
  private static final void dump(String prefix, byte[] b) {
    dump(prefix, b, 0, b.length>512?512:b.length);
  }

  /**
   * 输出哈希表内容。
   * @param prefix 输出前缀。
   * @param depth 最大dump深度。
   * @param map 输出的Map对象。
   */
  private static final void dump(String prefix,int depth,Vector checkCircuit,Map map){
    if (map==null) {
      dump(prefix,"null");
    }
    dumpBegin(prefix,checkCircuit,map);
    for (Iterator i = map.keySet().iterator();i.hasNext();){
      Object key = i.next();
      Object value = map.get(key);
      if (value instanceof String) {
        dump(indent(prefix),key.toString() + " = " + value);
      } else {
        dump(indent(prefix) + key.toString() + " = ",depth,checkCircuit,map.get(key));
      }
    }
    dumpEnd(prefix,checkCircuit,map);
  }

  /**
   * 输出字符串。
   * @param prefix 输出前缀。
   * @param str 输出的字符串。
   */
  private static final void dump(String prefix,String str) {
    out.println(prefix+str);
    out.flush();
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -