博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AOP AspectJ 切面 Android简单示例
阅读量:5763 次
发布时间:2019-06-18

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

Demo位置:  

配置

1、在【project】的build.gradle中配置:
buildscript {    repositories {        google()        jcenter()        mavenCentral()//【aspectj】需要依赖maven仓库    }    dependencies {        classpath 'com.android.tools.build:gradle:3.1.2'        classpath 'org.aspectj:aspectjtools:1.8.9'//【aspectj】编写gradle编译脚本        classpath 'org.aspectj:aspectjweaver:1.8.9'//【aspectj】编写gradle编译脚本    }}
 
1
buildscript {
2
   repositories {
3
       google()
4
       jcenter()
5
       mavenCentral()//【aspectj】需要依赖maven仓库
6
   }
7
   dependencies {
8
       classpath 'com.android.tools.build:gradle:3.1.2'
9
       classpath 'org.aspectj:aspectjtools:1.8.9'//【aspectj】编写gradle编译脚本
10
       classpath 'org.aspectj:aspectjweaver:1.8.9'//【aspectj】编写gradle编译脚本
11
   }
12
}
2、在【project】的build.gradle最后面添加脚本:
注意,直接粘贴到build.gradle文件的末尾即可,不要嵌套在别的指令中
//AOP需要执行的脚本,每一个application和library都需要import org.aspectj.bridge.MessageHandlerimport org.aspectj.tools.ajc.Maindef aop(variants) {    variants.all { variant ->        JavaCompile javaCompile = variant.javaCompile        String[] args;        javaCompile.doFirst {            args = ["-showWeaveInfo",                    "-1.8",                    "-inpath", javaCompile.destinationDir.toString(),                    "-aspectpath", javaCompile.classpath.asPath,                    "-d", javaCompile.destinationDir.toString(),                    "-classpath", path,                    "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]        }        javaCompile.doLast {            new Main().run(args, new MessageHandler(false));        }    }}
x
 
1
 
2
//AOP需要执行的脚本,每一个application和library都需要
3
import org.aspectj.bridge.MessageHandler
4
import org.aspectj.tools.ajc.Main
5
 
6
def aop(variants) {
7
   variants.all { variant ->
8
       JavaCompile javaCompile = variant.javaCompile
9
       String[] args;
10
       javaCompile.doFirst {
11
           args = ["-showWeaveInfo",
12
                   "-1.8",
13
                   "-inpath", javaCompile.destinationDir.toString(),
14
                   "-aspectpath", javaCompile.classpath.asPath,
15
                   "-d", javaCompile.destinationDir.toString(),
16
                   "-classpath", path,
17
                   "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]
18
       }
19
 
20
 
21
       javaCompile.doLast {
22
           new Main().run(args, new MessageHandler(false));
23
       }
24
   }
25
}
3、在【module】的build.gradle中添加依赖:
注意,每一个application和library都需要添加
implementation 'org.aspectj:aspectjrt:1.8.9'//每一个application和library都需要
 
1
implementation 'org.aspectj:aspectjrt:1.8.9'//每一个application和library都需要
4、在【module】的build.gradle中添加编译脚本:
注意,直接粘贴到build.gradle文件的末尾即可,不要嵌套在别的指令中
rootProject.aop(project.android.applicationVariants)//如果是【application】或rootProject.aop(project.android.libraryVariants)//如果是【library】
1
 
1
rootProject.aop(project.android.applicationVariants)//如果是【application】
2
3
rootProject.aop(project.android.libraryVariants)//如果是【library】

定义拦截点击事件的 Aspect

OnClickAspect
/** * 拦截所有View或其子类的【onClick方法】以及通过ButterKnife的注解添加的点击事件 */@Aspectpublic class OnClickAspect {	@Pointcut("execution(* android.view.View.On*Listener.on*Click(..)) ")//定义匹配范围:执行指定方法时拦截	public void onClick() {//匹配View.OnClickListener中的onClick方法和View.OnLongClickListener中的OnLongClickListener方法	}		@Pointcut("execution(* *.on*ItemClick(..)) ")//如果有多个匹配范围,可以定义多个,多个规则之间通过 || 或 && 控制	public void onItemClick() {//匹配任意名字以on开头以ItemClick结尾的方法	}		@Pointcut("execution(@butterknife.OnClick * *(..))")//匹配通过butterknife的OnClick注解添加的点击事件	public void butterKnifeOnClick() {	}		@Around("onClick() || onItemClick() || butterKnifeOnClick()")//@Around 拦截方法,这个注解可以同时拦截方法的执行前后	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {		long beginTime = SystemClock.currentThreadTimeMillis();		printJoinPointInfo(joinPoint);				if (joinPoint.getSignature() instanceof MethodSignature) {			MethodSignature signature = (MethodSignature) joinPoint.getSignature();//要根据Pointcut匹配的类型强转			printMethodSignatureInfo(signature);			printArgs(joinPoint);			printParameterInfo(joinPoint);		}				Object result = joinPoint.proceed();		Log.i("bqt", "【@Around】返回值=" + ObjToStringUtils.toString(result)// null				+ "  方法执行耗时=" + (SystemClock.currentThreadTimeMillis() - beginTime));//2		return result;	}		//必须是静态方法	private static void printJoinPointInfo(ProceedingJoinPoint joinPoint) {		Log.i("bqt", "【@Around】MethodSignature"				+ "\nKind=" + joinPoint.getKind()//method-execution				+ "\nArgs=" + ObjToStringUtils.toString(joinPoint.getArgs())//[android.widget.TextView{d090a1d V.ED..C.. ...P.... 0,0-1440,210}]				+ "\nSignature=" + ObjToStringUtils.toString(joinPoint.getSignature())//void com.bqt.aop.MainActivity.1.onClick(View)				+ "\nSourceLocation=" + ObjToStringUtils.toString(joinPoint.getSourceLocation())//MainActivity.java:25				+ "\nStaticPart=" + ObjToStringUtils.toString(joinPoint.getStaticPart())//execution(void com.bqt.aop.MainActivity.1.onClick(View))				+ "\nTarget=" + ObjToStringUtils.toString(joinPoint.getTarget())//com.bqt.aop.MainActivity$1@d5c5492				+ "\nThis=" + ObjToStringUtils.toString(joinPoint.getThis()));//com.bqt.aop.MainActivity$1@d5c5492	}		private static void printMethodSignatureInfo(MethodSignature signature) {		//下面通过MethodSignature的方式获取方法的详细信息,也基本都可以通过Method对象获取		Log.i("bqt", "【@Around】MethodSignature"				+ "\n方法=" + ObjToStringUtils.toString(signature.getMethod())// public void com.bqt.aop.MainActivity$1.onClick(android.view.View)				+ "\n方法名=" + signature.getName()// onClick				+ "\n返回值类型=" + ObjToStringUtils.toString(signature.getReturnType())// void				+ "\n声明类型=" + ObjToStringUtils.toString(signature.getDeclaringType())// class com.bqt.aop.MainActivity$1				+ "\n声明类型名=" + signature.getDeclaringTypeName()// com.bqt.aop.MainActivity$1				+ "\n异常类型=" + ObjToStringUtils.toString(signature.getExceptionTypes())// []				+ "\n修饰符=" + signature.getModifiers()// 1,对应为 public static final int PUBLIC  = 0x00000001				+ "\n参数名=" + ObjToStringUtils.toString(signature.getParameterNames())// ["v"]				+ "\n参数类型=" + ObjToStringUtils.toString(signature.getParameterTypes()));// [class android.view.View]	}		private static void printArgs(ProceedingJoinPoint joinPoint) {		String[] parameterNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();//获取参数名列表		Object[] parameterValues = joinPoint.getArgs();//获取参数值列表				StringBuilder builder = new StringBuilder("");		for (int i = 0; i < parameterValues.length; i++) {			builder.append("\n")					.append(parameterNames[i])					.append("=")//拼接参数名					.append(ObjToStringUtils.toString(parameterValues[i]));//拼接参数值		}		Log.i("bqt", "【@Around】参数列表" + builder.toString());//v=android.widget.TextView{d090a1d V.ED..C.. ...P.... 0,0-1440,210}	}		private static void printParameterInfo(ProceedingJoinPoint joinPoint) {		Object[] parameterValues = joinPoint.getArgs();//获取参数值列表		for (Object obj : parameterValues) {			if (obj instanceof TextView) {				TextView textView = (TextView) obj;				Log.i("bqt", "【@Around】TextView的信息"						+ "  文字=" + textView.getText()						+ "  所属界面=" + textView.getContext().getClass().getSimpleName()						+ "  ID=" + textView.getId()						+ "  父页面名称=" + textView.getParent().getClass().getSimpleName()				);			}		}	}}
1
90
 
1
/**
2
* 拦截所有View或其子类的【onClick方法】以及通过ButterKnife的注解添加的点击事件
3
*/
4
@Aspect
5
public class OnClickAspect {
6
@Pointcut("execution(* android.view.View.On*Listener.on*Click(..)) ")//定义匹配范围:执行指定方法时拦截
7
public void onClick() {
//匹配View.OnClickListener中的onClick方法和View.OnLongClickListener中的OnLongClickListener方法
8
}
9
 
10
@Pointcut("execution(* *.on*ItemClick(..)) ")//如果有多个匹配范围,可以定义多个,多个规则之间通过 || 或 && 控制
11
public void onItemClick() {
//匹配任意名字以on开头以ItemClick结尾的方法
12
}
13
 
14
@Pointcut("execution(@butterknife.OnClick * *(..))")//匹配通过butterknife的OnClick注解添加的点击事件
15
public void butterKnifeOnClick() {
16
}
17
 
18
@Around("onClick() || onItemClick() || butterKnifeOnClick()")//@Around 拦截方法,这个注解可以同时拦截方法的执行前后
19
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
20
long beginTime = SystemClock.currentThreadTimeMillis();
21
printJoinPointInfo(joinPoint);
22
 
23
if (joinPoint.getSignature() instanceof MethodSignature) {
24
MethodSignature signature = (MethodSignature) joinPoint.getSignature();//要根据Pointcut匹配的类型强转
25
printMethodSignatureInfo(signature);
26
printArgs(joinPoint);
27
printParameterInfo(joinPoint);
28
}
29
 
30
Object result = joinPoint.proceed();
31
Log.i("bqt", "【@Around】返回值=" + ObjToStringUtils.toString(result)// null
32
+ "  方法执行耗时=" + (SystemClock.currentThreadTimeMillis() - beginTime));//2
33
return result;
34
}
35
 
36
//必须是静态方法
37
private static void printJoinPointInfo(ProceedingJoinPoint joinPoint) {
38
Log.i("bqt", "【@Around】MethodSignature"
39
+ "\nKind=" + joinPoint.getKind()//method-execution
40
+ "\nArgs=" + ObjToStringUtils.toString(joinPoint.getArgs())//[android.widget.TextView{d090a1d V.ED..C.. ...P.... 0,0-1440,210}]
41
+ "\nSignature=" + ObjToStringUtils.toString(joinPoint.getSignature())//void com.bqt.aop.MainActivity.1.onClick(View)
42
+ "\nSourceLocation=" + ObjToStringUtils.toString(joinPoint.getSourceLocation())//MainActivity.java:25
43
+ "\nStaticPart=" + ObjToStringUtils.toString(joinPoint.getStaticPart())//execution(void com.bqt.aop.MainActivity.1.onClick(View))
44
+ "\nTarget=" + ObjToStringUtils.toString(joinPoint.getTarget())//com.bqt.aop.MainActivity$1@d5c5492
45
+ "\nThis=" + ObjToStringUtils.toString(joinPoint.getThis()));//com.bqt.aop.MainActivity$1@d5c5492
46
}
47
 
48
private static void printMethodSignatureInfo(MethodSignature signature) {
49
//下面通过MethodSignature的方式获取方法的详细信息,也基本都可以通过Method对象获取
50
Log.i("bqt", "【@Around】MethodSignature"
51
+ "\n方法=" + ObjToStringUtils.toString(signature.getMethod())// public void com.bqt.aop.MainActivity$1.onClick(android.view.View)
52
+ "\n方法名=" + signature.getName()// onClick
53
+ "\n返回值类型=" + ObjToStringUtils.toString(signature.getReturnType())// void
54
+ "\n声明类型=" + ObjToStringUtils.toString(signature.getDeclaringType())// class com.bqt.aop.MainActivity$1
55
+ "\n声明类型名=" + signature.getDeclaringTypeName()// com.bqt.aop.MainActivity$1
56
+ "\n异常类型=" + ObjToStringUtils.toString(signature.getExceptionTypes())// []
57
+ "\n修饰符=" + signature.getModifiers()// 1,对应为 public static final int PUBLIC  = 0x00000001
58
+ "\n参数名=" + ObjToStringUtils.toString(signature.getParameterNames())// ["v"]
59
+ "\n参数类型=" + ObjToStringUtils.toString(signature.getParameterTypes()));// [class android.view.View]
60
}
61
 
62
private static void printArgs(ProceedingJoinPoint joinPoint) {
63
String[] parameterNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();//获取参数名列表
64
Object[] parameterValues = joinPoint.getArgs();//获取参数值列表
65
 
66
StringBuilder builder = new StringBuilder("");
67
for (int i = 0; i < parameterValues.length; i++) {
68
builder.append("\n")
69
.append(parameterNames[i])
70
.append("=")//拼接参数名
71
.append(ObjToStringUtils.toString(parameterValues[i]));//拼接参数值
72
}
73
Log.i("bqt", "【@Around】参数列表" + builder.toString());//v=android.widget.TextView{d090a1d V.ED..C.. ...P.... 0,0-1440,210}
74
}
75
 
76
private static void printParameterInfo(ProceedingJoinPoint joinPoint) {
77
Object[] parameterValues = joinPoint.getArgs();//获取参数值列表
78
for (Object obj : parameterValues) {
79
if (obj instanceof TextView) {
80
TextView textView = (TextView) obj;
81
Log.i("bqt", "【@Around】TextView的信息"
82
+ "  文字=" + textView.getText()
83
+ "  所属界面=" + textView.getContext().getClass().getSimpleName()
84
+ "  ID=" + textView.getId()
85
+ "  父页面名称=" + textView.getParent().getClass().getSimpleName()
86
);
87
}
88
}
89
}
90
}

定义拦截自定义注解的 Aspect

@Target({METHOD, CONSTRUCTOR})@Retention(RetentionPolicy.RUNTIME)public @interface CustomEvent {	String key();		String id() default "";		String name() default "";		String des() default "";}
11
11
 
1
@Target({
METHOD, CONSTRUCTOR})
2
@Retention(RetentionPolicy.RUNTIME)
3
public @interface CustomEvent {
4
String key();
5
 
6
String id() default "";
7
 
8
String name() default "";
9
 
10
String des() default "";
11
}
package com.bqt.aop.aspectj;import android.util.Log;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.Signature;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.ConstructorSignature;import org.aspectj.lang.reflect.MethodSignature;import java.lang.reflect.Constructor;import java.lang.reflect.Method;/** * 拦截所有具有【CustomEvent注解】的方法、构造方法 */@Aspectpublic class CustomEventAspect {	@Pointcut("within(@com.bqt.aop.aspectj.CustomEvent *)")	public void withinAnnotatedClass() {	}		@Pointcut("execution(* *(..)) && withinAnnotatedClass()")	public void methodInsideAnnotatedType() {	}		@Pointcut("execution(*.new(..)) && withinAnnotatedClass()")	public void constructorInsideAnnotatedType() {	}		@Pointcut("execution(@com.bqt.aop.aspectj.CustomEvent * *(..)) || methodInsideAnnotatedType()")	public void method() {	}		@Pointcut("execution(@com.bqt.aop.aspectj.CustomEvent *.new(..)) || constructorInsideAnnotatedType()")	public void constructor() {	}		@Before("method() || constructor()")	public void before(JoinPoint joinPoint) {		Log.i("bqt", "【@Before】");	}		@After("method() || constructor()")	public void after(JoinPoint joinPoint) {		Log.i("bqt", "【@After】");		addEvent(joinPoint);	}		private static void addEvent(JoinPoint joinPoint) {		CustomEvent customEvent = null;		Signature signature = joinPoint.getSignature();		if (signature instanceof MethodSignature) {//【public interface MethodSignature extends CodeSignature】			Method method = ((MethodSignature) signature).getMethod();			customEvent = method.getAnnotation(CustomEvent.class);		} else if (signature instanceof ConstructorSignature) {//【public interface ConstructorSignature extends CodeSignature】			Constructor constructor = ((ConstructorSignature) signature).getConstructor();			customEvent = (CustomEvent) constructor.getAnnotation(CustomEvent.class);		}		if (customEvent != null) {			Log.i("bqt", "【注解】" + customEvent.key() + "  " + customEvent.id() + "  " + customEvent.name() + "  " + customEvent.des());		}			}}
x
68
 
1
package com.bqt.aop.aspectj;
2
 
3
import android.util.Log;
4
 
5
import org.aspectj.lang.JoinPoint;
6
import org.aspectj.lang.Signature;
7
import org.aspectj.lang.annotation.After;
8
import org.aspectj.lang.annotation.Aspect;
9
import org.aspectj.lang.annotation.Before;
10
import org.aspectj.lang.annotation.Pointcut;
11
import org.aspectj.lang.reflect.ConstructorSignature;
12
import org.aspectj.lang.reflect.MethodSignature;
13
 
14
import java.lang.reflect.Constructor;
15
import java.lang.reflect.Method;
16
 
17
/**
18
* 拦截所有具有【CustomEvent注解】的方法、构造方法
19
*/
20
@Aspect
21
public class CustomEventAspect {
22
@Pointcut("within(@com.bqt.aop.aspectj.CustomEvent *)")
23
public void withinAnnotatedClass() {
24
}
25
 
26
@Pointcut("execution(* *(..)) && withinAnnotatedClass()")
27
public void methodInsideAnnotatedType() {
28
}
29
 
30
@Pointcut("execution(*.new(..)) && withinAnnotatedClass()")
31
public void constructorInsideAnnotatedType() {
32
}
33
 
34
@Pointcut("execution(@com.bqt.aop.aspectj.CustomEvent * *(..)) || methodInsideAnnotatedType()")
35
public void method() {
36
}
37
 
38
@Pointcut("execution(@com.bqt.aop.aspectj.CustomEvent *.new(..)) || constructorInsideAnnotatedType()")
39
public void constructor() {
40
}
41
 
42
@Before("method() || constructor()")
43
public void before(JoinPoint joinPoint) {
44
Log.i("bqt", "【@Before】");
45
}
46
 
47
@After("method() || constructor()")
48
public void after(JoinPoint joinPoint) {
49
Log.i("bqt", "【@After】");
50
addEvent(joinPoint);
51
}
52
 
53
private static void addEvent(JoinPoint joinPoint) {
54
CustomEvent customEvent = null;
55
Signature signature = joinPoint.getSignature();
56
if (signature instanceof MethodSignature) {
//【public interface MethodSignature extends CodeSignature】
57
Method method = ((MethodSignature) signature).getMethod();
58
customEvent = method.getAnnotation(CustomEvent.class);
59
} else if (signature instanceof ConstructorSignature) {
//【public interface ConstructorSignature extends CodeSignature】
60
Constructor constructor = ((ConstructorSignature) signature).getConstructor();
61
customEvent = (CustomEvent) constructor.getAnnotation(CustomEvent.class);
62
}
63
if (customEvent != null) {
64
Log.i("bqt", "【注解】" + customEvent.key() + "  " + customEvent.id() + "  " + customEvent.name() + "  " + customEvent.des());
65
}
66
 
67
}
68
}

一个实用的工具类

ObjToStringUtils
public class ObjToStringUtils {		private ObjToStringUtils() {		throw new AssertionError("No instances.");	}		public static String toString(Object obj) {		if (obj == null) return "null";		if (obj instanceof CharSequence) return '"' + printableToString(obj.toString()) + '"';				Class
cls = obj.getClass(); if (Byte.class == cls) return byteToString((Byte) obj); if (cls.isArray()) return arrayToString(cls.getComponentType(), obj); return obj.toString(); } private static String printableToString(String string) { int length = string.length(); StringBuilder builder = new StringBuilder(length); for (int i = 0; i < length; ) { int codePoint = string.codePointAt(i); switch (Character.getType(codePoint)) { case Character.CONTROL: case Character.FORMAT: case Character.PRIVATE_USE: case Character.SURROGATE: case Character.UNASSIGNED: switch (codePoint) { case '\n': builder.append("\\n"); break; case '\r': builder.append("\\r"); break; case '\t': builder.append("\\t"); break; case '\f': builder.append("\\f"); break; case '\b': builder.append("\\b"); break; default: builder.append("\\u").append(String.format("%04x", codePoint).toUpperCase(Locale.US)); break; } break; default: builder.append(Character.toChars(codePoint)); break; } i += Character.charCount(codePoint); } return builder.toString(); } private static String arrayToString(Class
cls, Object obj) { if (byte.class == cls) return byteArrayToString((byte[]) obj); if (short.class == cls) return Arrays.toString((short[]) obj); if (char.class == cls) return Arrays.toString((char[]) obj); if (int.class == cls) return Arrays.toString((int[]) obj); if (long.class == cls) return Arrays.toString((long[]) obj); if (float.class == cls) return Arrays.toString((float[]) obj); if (double.class == cls) return Arrays.toString((double[]) obj); if (boolean.class == cls) return Arrays.toString((boolean[]) obj); return arrayToString((Object[]) obj); } /** * A more human-friendly version of Arrays#toString(byte[]) that uses hex representation. */ private static String byteArrayToString(byte[] bytes) { StringBuilder builder = new StringBuilder("["); for (int i = 0; i < bytes.length; i++) { if (i > 0) builder.append(", "); builder.append(byteToString(bytes[i])); } return builder.append(']').toString(); } private static String byteToString(Byte b) { if (b == null) return "null"; return "0x" + String.format("%02x", b).toUpperCase(Locale.US); } private static String arrayToString(Object[] array) { StringBuilder buf = new StringBuilder(); arrayToString(array, buf, new HashSet
()); return buf.toString(); } private static void arrayToString(Object[] array, StringBuilder builder, Set
seen) { if (array == null) { builder.append("null"); return; } seen.add(array); builder.append('['); for (int i = 0; i < array.length; i++) { if (i > 0) builder.append(", "); Object element = array[i]; if (element == null) { builder.append("null"); } else { Class elementClass = element.getClass(); if (elementClass.isArray() && elementClass.getComponentType() == Object.class) { Object[] arrayElement = (Object[]) element; if (seen.contains(arrayElement)) builder.append("[...]"); else arrayToString(arrayElement, builder, seen); } else { builder.append(toString(element)); } } } builder.append(']'); seen.remove(array); }}
122
 
1
public class ObjToStringUtils {
2
 
3
private ObjToStringUtils() {
4
throw new AssertionError("No instances.");
5
}
6
 
7
public static String toString(Object obj) {
8
if (obj == null) return "null";
9
if (obj instanceof CharSequence) return '"' + printableToString(obj.toString()) + '"';
10
 
11
Class
cls = obj.getClass();
12
if (Byte.class == cls) return byteToString((Byte) obj);
13
if (cls.isArray()) return arrayToString(cls.getComponentType(), obj);
14
 
15
return obj.toString();
16
}
17
 
18
private static String printableToString(String string) {
19
int length = string.length();
20
StringBuilder builder = new StringBuilder(length);
21
for (int i = 0; i < length; ) {
22
int codePoint = string.codePointAt(i);
23
switch (Character.getType(codePoint)) {
24
case Character.CONTROL:
25
case Character.FORMAT:
26
case Character.PRIVATE_USE:
27
case Character.SURROGATE:
28
case Character.UNASSIGNED:
29
switch (codePoint) {
30
case '\n':
31
builder.append("\\n");
32
break;
33
case '\r':
34
builder.append("\\r");
35
break;
36
case '\t':
37
builder.append("\\t");
38
break;
39
case '\f':
40
builder.append("\\f");
41
break;
42
case '\b':
43
builder.append("\\b");
44
break;
45
default:
46
builder.append("\\u").append(String.format("%04x", codePoint).toUpperCase(Locale.US));
47
break;
48
}
49
break;
50
default:
51
builder.append(Character.toChars(codePoint));
52
break;
53
}
54
i += Character.charCount(codePoint);
55
}
56
return builder.toString();
57
}
58
 
59
private static String arrayToString(Class
cls, Object obj) {
60
if (byte.class == cls) return byteArrayToString((byte[]) obj);
61
if (short.class == cls) return Arrays.toString((short[]) obj);
62
if (char.class == cls) return Arrays.toString((char[]) obj);
63
if (int.class == cls) return Arrays.toString((int[]) obj);
64
if (long.class == cls) return Arrays.toString((long[]) obj);
65
if (float.class == cls) return Arrays.toString((float[]) obj);
66
if (double.class == cls) return Arrays.toString((double[]) obj);
67
if (boolean.class == cls) return Arrays.toString((boolean[]) obj);
68
return arrayToString((Object[]) obj);
69
}
70
 
71
/**
72
* A more human-friendly version of Arrays#toString(byte[]) that uses hex representation.
73
*/
74
private static String byteArrayToString(byte[] bytes) {
75
StringBuilder builder = new StringBuilder("[");
76
for (int i = 0; i < bytes.length; i++) {
77
if (i > 0) builder.append(", ");
78
builder.append(byteToString(bytes[i]));
79
}
80
return builder.append(']').toString();
81
}
82
 
83
private static String byteToString(Byte b) {
84
if (b == null) return "null";
85
return "0x" + String.format("%02x", b).toUpperCase(Locale.US);
86
}
87
 
88
private static String arrayToString(Object[] array) {
89
StringBuilder buf = new StringBuilder();
90
arrayToString(array, buf, new HashSet
());
91
return buf.toString();
92
}
93
 
94
private static void arrayToString(Object[] array, StringBuilder builder, Set
seen) {
95
if (array == null) {
96
builder.append("null");
97
return;
98
}
99
 
100
seen.add(array);
101
builder.append('[');
102
for (int i = 0; i < array.length; i++) {
103
if (i > 0) builder.append(", ");
104
 
105
Object element = array[i];
106
if (element == null) {
107
builder.append("null");
108
} else {
109
Class elementClass = element.getClass();
110
if (elementClass.isArray() && elementClass.getComponentType() == Object.class) {
111
Object[] arrayElement = (Object[]) element;
112
if (seen.contains(arrayElement)) builder.append("[...]");
113
else arrayToString(arrayElement, builder, seen);
114
} else {
115
builder.append(toString(element));
116
}
117
}
118
}
119
builder.append(']');
120
seen.remove(array);
121
}
122
}
2018-4-27

转载地址:http://tqgkx.baihongyu.com/

你可能感兴趣的文章
WML处理---H_wml.php
查看>>
WSS开发,搜索(SPQuery)时出现Invalid column name c2错误 (转载)
查看>>
JAVA位运算
查看>>
修改Android开机画面
查看>>
Pandas 基础(2) - Dataframe 基础
查看>>
不同设备的视口
查看>>
【资源共享】休眠唤醒 开发指南
查看>>
四种排序:bubbleSort,insertSort,selectSort,quickSort
查看>>
软件测试提升建议
查看>>
交叉编译问题记录-嵌入式环境下 GDB 的使用方法
查看>>
Algs4-1.1.3参个数是否相等
查看>>
Algs4-2.4.13去掉sink()中的检查j<N
查看>>
天佑九寨,天佑新疆!
查看>>
HTML5、CSS3等新特性:
查看>>
FTP作业
查看>>
优化REST Framework 的 路由 APIView 和ViewSetMixin
查看>>
递归在PHP中的应用举例
查看>>
面试题1 英特利11-04
查看>>
使用ganglia监控hadoop及hbase集群
查看>>
iTween基础之iTweenPath(自定义路径移动)
查看>>