java lambda format umformulieren?
Hallo,
ich würde gerne wissen wie es möglich ist den folgenden code von lambda zu java 6 code umwandeln kann?
if(name.equals(itemStackName) || transformedName.equals(itemStackName)) {
node.methods.stream().filter(methodNode -> methodNode.name.equals(getTooltipName) && methodNode.desc.equals(getTooltipDesc)).findFirst()
.ifPresent(methodNode -> {
InsnList list = new InsnList();
String onTooltipDesc = "(L"+itemStackName.replace(".", "/")+";L"+entityPlayerName.replace(".", "/")+";Ljava/util/List;Z)V";
list.add(new VarInsnNode(Opcodes.ALOAD, 0));
list.add(new VarInsnNode(Opcodes.ALOAD, 1));
list.add(new VarInsnNode(Opcodes.ALOAD, 3));
list.add(new VarInsnNode(Opcodes.ILOAD, 2));
methodNode.instructions.insert(methodNode.instructions.getLast().getPrevious().getPrevious(), list);
});
}
Also von z.b. von Runnable r = ()-> System.out.print("Run method")
zu
Runnable r = new Runnable() {
@Override
public void run() {
System.out.print("Run method")
}
}
Ich würde gerne wissen wie das möglich ist. Also wie die if Abfrage von ganz oben ohne "->" aussehen würde.
Mit freundlichen Grüßen
2 Antworten
Damals hätte man einfach mit einer for-Schleife nach einer Methode gesucht, die die Kriterien erfüllt.
Ich denke mal node.methods wird eine List<Method> sein, oder? Evtl. musst du statt Method was anderes einsetzen, den genauen Typ kann ich anhand des Codes nicht sehen.
Das hätte etwa so ausgesehen:
if(name.equals(itemStackName) || transformedName.equals(itemStackName)) {
for (int methodId = 0; methodId < node.methods.size(); ++methodId) {
Method method = node.methods.get(methodId);
if (methodNode.name.equals(getTooltipName) && methodNode.desc.equals(getTooltipDesc)) {
InsnList list = new InsnList();
String onTooltipDesc = "(L"+itemStackName.replace(".", "/")+";L"+entityPlayerName.replace(".", "/")+";Ljava/util/List;Z)V";
list.add(new VarInsnNode(Opcodes.ALOAD, 0));
list.add(new VarInsnNode(Opcodes.ALOAD, 1));
list.add(new VarInsnNode(Opcodes.ALOAD, 3));
list.add(new VarInsnNode(Opcodes.ILOAD, 2));
break; // Damit nur die erste passende Method verarbeitet wird
}
}
}
@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
// Classes
final String itemStackName = LabyModCoreMod.isObfuscated() ? "zx" : "net.minecraft.item.ItemStack";
final String entityPlayerName = LabyModCoreMod.isObfuscated() ? "wn" : "net.minecraft.entity.player.EntityPlayer";
final String labyModApiName = "net.labymod.api.LabyModAPI";
// Methods
final String getTooltipName = LabyModCoreMod.isObfuscated() ? "a" : "getTooltip";
// Method descriptors
final String getTooltipDesc = LabyModCoreMod.isObfuscated() ? "(Lwn;Z)Ljava/util/List;" : "(Lnet/minecraft/entity/player/EntityPlayer;Z)Ljava/util/List;";
ClassNode node = new ClassNode();
ClassReader reader = new ClassReader(basicClass);
reader.accept(node, 0);
if(name.equals(itemStackName) || transformedName.equals(itemStackName)) {
node.methods.stream().filter(methodNode -> methodNode.name.equals(getTooltipName) && methodNode.desc.equals(getTooltipDesc)).findFirst()
.ifPresent(methodNode -> {
InsnList list = new InsnList();
String onTooltipDesc = "(L"+itemstackName.replace(".", "/")+";L"+entityPlayerName.replace(".", "/")+";Ljava/util/List;Z)V";
list.add(new VarInsnNode(Opcodes.ALOAD, 0));
list.add(new VarInsnNode(Opcodes.ALOAD, 1));
list.add(new VarInsnNode(Opcodes.ALOAD, 3));
list.add(new VarInsnNode(Opcodes.ILOAD, 2));
methodNode.instructions.insert(methodNode.instructions.getLast().getPrevious().getPrevious(), list);
});
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
node.accept(writer);
return writer.toByteArray();
}
Du kannst eine klassische Schleife verwenden.
Da ich nicht weiß, welchen Typ node.methods speichert, habe ich den hier als T betitelt.
T methodNode = null;
for (T currentMethodNode : node.methods) {
if (currentMethodNode.name.equals(getTooltipName) && currentMethodNode.desc.equals(getTooltipDesc)) {
methodNode = currentMethodNode;
break;
}
}
if (methodNode != null) {
InsnList list = new InsnList();
/* etc. ... */
}