gpt4 book ai didi

java - Byte Buddy : java. lang.AbstractMethodError:调用方法时出错

转载 作者:行者123 更新时间:2023-11-30 07:08:03 24 4
gpt4 key购买 nike

编辑

原始问题中的实际界面和示例域存在缺陷。这是正确的例子。

import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy;
import static net.bytebuddy.matcher.ElementMatchers.isGetter;
import static net.bytebuddy.matcher.ElementMatchers.isSetter;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.FieldAccessor;

public class Example {

public interface Domain {
int getIdentifier();
}

public class Person implements Domain {

private int personId;
private String firstName;
private String lastName;

@Override
public int getIdentifier() {
return personId;
}

public int getPersonId() {
return personId;
}

public void setPersonId(final int personId) {
this.personId = personId;
}

// further getters and setters ommitted

}

public static void main(final String[] args) throws InstantiationException, IllegalAccessException {
final Domain domain = new ByteBuddy()
.subclass(Domain.class)
.name("Person")
.method(isGetter().or(isSetter())).intercept(FieldAccessor.ofBeanProperty())
.defineField("personId", int.class, Visibility.PRIVATE)
.defineField("firstName", String.class, Visibility.PRIVATE)
.defineField("lastName", String.class, Visibility.PRIVATE)
.method(isDeclaredBy(Domain.class))
.intercept(FieldAccessor.ofField("personId"))
.make()
.load(Example.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded()
.newInstance();

System.out.println(domain.getIdentifier());

}
}

Byte Buddy 代码是否按照上述代码生成 Person 类? (我该如何检查?)

预编辑

我正在尝试在运行时生成一些使用 Byte Buddy API 实现域接口(interface)的类 ( http://bytebuddy.net/#/ )

应用程序从外部源获取一些输入,我想将该输入(例如类名、某些变量的名称)转换为实现接口(interface)的 POJO。在下面的示例代码中,输入由域名字符串数组表示。

成功生成代码后,我想使用那些在运行时生成的类来映射文件(例如解析行并将它们映射到生成的 POJO)。

以下代码 (clazz.setIdentifier(1);) 会在线程“main”java.lang.AbstractMethodError: Person.setIdentifier(I)V 中引发 异常:Person.setIdentifier(I)V

public class Sample {

public interface Domain {
void setIdentifier(int i);
int getIdentifier();
}

public static void main(String[] args) throws InstantiationException, IllegalAccessException {
String[] domainNames = {"Person", "City", "Country"};
for (String domainName : domainNames) {
Class<?> domain = new ByteBuddy()
.subclass(Domain.class)
.name(domainName)
.method(ElementMatchers.named("getIdentifier"))
.intercept(FixedValue.value(1))
.make()
.load(Sample.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();

Domain clazz = (Domain) domain.newInstance();
clazz.setIdentifier(1);
System.out.println(clazz.getIdentifier());
}
}
}

现在我正在使用 Roaster 生成以下类:

public class Adres implements Domain {

@Parsed(index = 0)
private int id;
@Parsed(index = 1)
private String plaatsNaam;
@Parsed(index = 2)
private String straatNaam;
@Parsed(index = 3)
private String huisnummer;
@Parsed(index = 4)
private String postcode;

@Override
public int getIdentifier() {
return id;
}
}

但是外部源输入的不断变化的性质使得运行时代码生成比源代码生成更可取。因此,理想情况下,我想在运行时创建上述代码,然后使用该代码(显然)。

http://bytebuddy.net/#/tutorial 的字段和方法部分确实提到了 ElementMatchers 和 Interceptors 的使用,但坦率地说,我不知道如何让它们工作。

问题:如何创建一个使用 Byte Buddy 实现接口(interface)的 POJO,然后在生成的代码上调用方法?

最佳答案

您永远不会实现setIdentifier方法。因此,该方法仍然是抽象的,并且会抛出AbstractMethodError。虽然 javac 禁止这样做,但 VM 允许您加载此类类型,因此 Byte Buddy 也允许这样做。就您而言,这当然不是期望的结果。您可能想要使用 FieldAccessor 实现执行如下操作:

Domain domain = new ByteBuddy()
.subclass(Domain.class)
.method(isDeclaredBy(Domain.class))
.intercept(FieldAccessor.ofField("id").defineAs(int.class, Visibility.PRIVATE))
.make()
.load(Sample.class.getClassLoader())
.getLoaded()
.newInstance();

domain.setIdentifier(42);
System.out.println(domain.getIdentifier());

在上面的 Adres 示例中,setter 实现也丢失了;我假设您忘记了这一点,但如果情况并非如此,请要求澄清。

编辑:您更新的示例仍然建议采用这种方法,但您需要手动定义 setter 和 getter。我计划在某个时候为此添加一个便利的 API,但您应该能够在属性列表的循环中执行此操作。您可以通过在生成的类上使用反射 API 或通过使用 Java 反编译器查看生成的类文件的反汇编来进行验证。

关于java - Byte Buddy : java. lang.AbstractMethodError:调用方法时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39733284/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com