1 表情符號源代碼
https://github.com/zly394/EmojiRegex/blob/master/src/main/java/com/zly/utils/EmojiRegexUtil.java
2 測試用例
import java.lang.instrument.Instrumentation;
public class Main2 {
public static void main(String[] args) {
String text = "\uD83C\uDDF2\uD83C\uDDEA\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDE8\uD83C\uDDF3\uD83C\uDDEC\uD83C\uDDE7\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73\uDB40\uDC7F\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74\uDB40\uDC7F\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67\uDB40\uDC7F";
boolean allEmoji = EmojiUtil.isAllEmoji(text);
System.out.println(allEmoji);
}
public static void premain(String args, Instrumentation inst) {
inst.addTransformer(new MethodCallCountTransformer());
}
}
// 增強類
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
public class MethodCallCountTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws
IllegalClassFormatException {
try {
if (!"java/util/regex/Pattern$CharProperty".equals(className)
&&
!"java/util/regex/Pattern$BmpCharProperty".equals(className)) {
return classfileBuffer;
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassAdapter adapter = new MethodCallClassAdapter(writer, className);
ClassReader reader = new ClassReader(classfileBuffer);
reader.accept(adapter, 0);
return writer.toByteArray();
}catch (Exception e){
return classfileBuffer;
}
}
}
// MethodCallClassAdapter
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
public class MethodCallClassAdapter extends ClassAdapter {
private String className;
public MethodCallClassAdapter(ClassVisitor cv, String className) {
//Responsechain 的下一個 ClassVisitor,這裏我們將傳入 ClassWriter,
// 負責改寫後代碼的輸出
super(cv);
this.className = className;
}
// 重寫 visitMethod,訪問到 "operation" 方法時,
// 給出自定義 MethodVisitor,實際改寫方法內容
@Override
public MethodVisitor visitMethod(final int access, final String name,
final String desc, final String signature, final String[] exceptions) {
MethodVisitor mv = cv.visitMethod(access, name, desc, signature,exceptions);
MethodVisitor wrappedMv = mv;
if (mv != null) {
// 對於 "operation" 方法
if (name.equals("match")) {
// 使用自定義 MethodVisitor,實際改寫方法內容
wrappedMv = new CountCallMethodAdapter(mv,name,name);
}
}
return wrappedMv;
}
}
// MethodAdapter
import org.objectweb.asm.MethodAdapter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class CountCallMethodAdapter extends MethodAdapter {
private String methodName;
private String className;
public CountCallMethodAdapter(MethodVisitor visitor, String className, String methodName) {
super(visitor);
this.methodName = methodName;
this.className = className;
}
@Override
public void visitCode() {
visitMethodInsn(Opcodes.INVOKESTATIC, "com/you/gbrank/asm/counter/Counter", "printAndIncCount", "()V");
}
}
3 Counter 類
import java.util.concurrent.atomic.AtomicInteger;
public class Counter {
private static AtomicInteger methodCallCount = new AtomicInteger(0);
public static void checkSecurity() {
System.out.println("SecurityChecker.checkSecurity ...");
//TODO real security check
}
public static void printAndIncCount() {
System.out.println(methodCallCount.incrementAndGet());
}
public static void printAndIncCount1(String className, String methodName) {
System.out.println(methodCallCount.get());
System.out.println(className + "." + methodName + " called, total times " + methodCallCount.incrementAndGet());
}
}
4 結果:增強沒有效果,沒有任何日誌打印。 MARK
5 https://blog.csdn.net/qfzhangwei/article/details/105117126 給出了一個解決方案