Как можно изменить имя класса из главного метода?
Да не слушайте вы их, можно, конечно можно и даже в рантайме, только стоит ли игра свеч? (: И что бы не быть голосовым - проект и туториал; не по теме вопроса, но о библиотеке гайд. А вот даже рабочий(почти) пример. Меняет ваш Date
на DateInsane
, и в нагрузку все приватные методы делает публичными. Правда дебажить, то ещё удовольствие.
private Class<?> magicTransform(Class clazz, List<String> list, boolean fillInnerClasses) {
String defineName = clazz.getName().concat("Insane");
String className = clazz.getName().replace(".", "/");
String defineClassName = defineName.replace(".", "/");
class AssertorMethodAdapter extends ClassVisitor {
private AssertorMethodAdapter(ClassVisitor cv) {
super(ASM4, cv);
this.cv = cv;
}
private String replaceIfContains(String s) {
return replaceIfContains(s, className, defineClassName);
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, replaceIfContains(name), signature, superName, interfaces);
}
@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
super.visitInnerClass(replaceIfContains(name), replaceIfContains(outerName), innerName, access);
}
@Override
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
return super.visitField(access, name, replaceIfContains(desc), signature, value);
}
@Override
public void visitAttribute(Attribute attr) {
super.visitAttribute(attr);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
MethodVisitor mvno = new MethodVisitor(ASM5, cv.visitMethod(
list.contains(name) ? (access == ACC_PRIVATE ? ACC_PUBLIC : access) : access,
name, replaceIfContains(desc), replaceIfContains(signature), exceptions)) {
@Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
for (int i = 0; i < bsmArgs.length; i++) {
if (bsmArgs[i] instanceof String) {
bsmArgs[i] = replaceIfContains(((String) bsmArgs[i]));
}
}
super.visitInvokeDynamicInsn(name, replaceIfContains(desc),
new Handle(bsm.getTag(), replaceIfContains(bsm.getOwner()),
replaceIfContains(bsm.getName()), replaceIfContains(bsm.getDesc()),
bsm.isInterface()), bsmArgs);
}
@Override
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
super.visitLocalVariable(name, replaceIfContains(desc), replaceIfContains(signature), start, end, index);
}
@Override
public void visitLdcInsn(Object cst) {
if (Type.getDescriptor(clazz).equals(cst.toString())) {
super.visitLdcInsn(Type.getObjectType(defineClassName));
} else {
super.visitLdcInsn(cst);
}
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
super.visitFieldInsn(opcode, replaceIfContains(owner), name, replaceIfContains(desc));
}
@Override
public void visitParameter(String name, int access) {
super.visitParameter(replaceIfContains(name), access);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
super.visitMethodInsn(opcode, replaceIfContains(owner), name, replaceIfContains(desc), itf);
}
@Override
public void visitTypeInsn(int opcode, String type) {
super.visitTypeInsn(opcode, replaceIfContains(type));
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return super.visitAnnotation(desc, visible);
}
@Override
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
for (int i = 0; i < local.length; i++) {
if (local[i] instanceof String) {
local[i] = replaceIfContains(((String) local[i]));
}
}
super.visitFrame(type, nLocal, local, nStack, stack);
}
};
return mvno;
}
}
try {
ClassReader reader = new ClassReader(clazz.getName());
ClassWriter writer = new ClassWriter(reader, 0);
AssertorMethodAdapter adapter = new AssertorMethodAdapter(writer);
reader.accept(adapter, 0);
byte[] bytes = writer.toByteArray();
Method defineClass = PluginsUtil.getPrivateMethod(ClassLoader.class, "defineClass",
new Class[]{String.class, byte[].class, int.class, int.class});
defineClass.invoke(clazz.getClassLoader(), defineName, bytes, 0, bytes.length);
if (fillInnerClasses) {
ClassNode cn = new ClassNode();
reader.accept(cn, 0);
Map<String, byte[]> innerClasses = cn.innerClasses.stream()
.filter(innerClassNode -> innerClassNode.name.contains(className)).collect(Collectors.toMap(
(innerClassNode) -> replaceIfContains(innerClassNode.name, className, defineClassName),
innerClassNode -> {
try {
ClassReader r = new ClassReader(innerClassNode.name);
ClassWriter w = new ClassWriter(r, 0);
AssertorMethodAdapter a = new AssertorMethodAdapter(w);
r.accept(a, 0);
return w.toByteArray();
} catch (IOException e) {
e.printStackTrace();
return new byte[0];
}
}));
innerClasses.forEach((name, bytes1) -> {
try {
defineClass.invoke(clazz.getClassLoader(), name.replace("/", "."), bytes1, 0, bytes1.length);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
});
}
return clazz.getClassLoader().loadClass(defineName);
} catch (IOException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) {
e.printStackTrace();
}
return clazz;
}
private String replaceIfContains(String s, String containString, String replaceString) {
if (s == null) {
return null;
}
return s.contains(containString) ? s.replace(containString, replaceString) : s;
}
Никак. После того, как вы написали класс (например Data
) и скомпилировали программу, имя класса нельзя изменить. Data
всегда будет Data
. Я считаю, что какая бы проблема у вас в данный момент не возникла, ее можно решить по-другому, без изменения имени класса.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Делаю приложение используя Spring MVC и Spring Web Flow, сделав некий flow я могу попасть на него используя ${flowExecutionUrl} в JSP файле, но из-за некой, невиданной...
Изучаю Герберта Шилдта Java 8 Руководство для начинающих, и вопрос в следующемСогласно книге метод synchronized обязан дать выполниться методу до завершения...
Каким образом можно сделать чтобы точка 0, 0 не была в низу слева, а чтобы она была вверху слева? Пробовал glOrtho(0D, 640D, 480D, 0D, 0D, 0D), но он ничего не делает
надо сделать див такого плана, и чтобы дочерние элементы были в закрашенной области, можно так сделать?