Мне нужно создать класс с обновленным частным полем.
Это мой код:
public class ByteBuddyTest {
public static class Foo {
}
public static class Bar {
private Foo foo;
public Foo getFoo() {
return foo;
}
}
public static void main(String[] args) throws Exception{
Class<? extends Bar> clazz = new ByteBuddy()
.subclass(Bar.class)
.??? //LINE X
.make()
.load(ByteBuddyTest.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
var bar1 = clazz
.getDeclaredConstructor()
.newInstance();
System.out.println(bar1.getFoo());
}
}
В line X мне нужно установить новый экземпляр Foo в поле Bar.foo для каждого экземпляра Bar. Обратите внимание, что мне нужно создать много экземпляров Bar, поэтому я хочу создать класс с ByteByddy только один раз. Может ли кто-нибудь сказать, как это сделать?
@TimRoberts Я использовал статические классы только для этого примера. В реальном приложении используются «обычные» классы.
Вам следует хорошо подумать, прежде чем нарушать инкапсуляцию таким образом. Это может легко вызвать ошибки. Тем не менее, бывают редкие случаи, когда это необходимо, например. чтобы обойти ошибку в устаревшей системе, которую вы не можете изменить. Однако для этого вам не нужен ByteBuddy, и я не думаю, что это облегчит задачу. Вы можете сделать это с помощью стандартного отражения. Я закрываю как дубликат.
@MatthewFlaschen Спасибо за ваш комментарий. А теперь, пожалуйста, снова откройте этот вопрос. Этот вопрос о байт-приятеле, но теперь об отражении. Вы видите разницу? Если бы я использовал отражение, я бы задал вопрос об отражении, не так ли? Но мне пришлось создать сложный класс с byte-buddy со множеством различных функций. Я почти сделал это, за исключением настройки частного поля. Итак, это не дубликат. Итак, еще раз, пожалуйста, снова откройте вопрос.
«Мне пришлось создать сложный класс с byte-buddy со множеством различных функций». Это ключевой контекст, о котором не идет речь. Обновите свой вопрос, чтобы объяснить, для чего вы используете ByteBuddy, тогда я снова открою его.
@MatthewFlaschen Я ясно сказал в своем вопросе, что речь шла о байт-приятеле. Это ваша вина, что вы (не знаю почему) решили, что ответом на размышление может стать ответ. Так что обновлять не буду.




Byte Buddy создает классы Java, и эти классы должны соответствовать тем же правилам, как если бы вы писали класс вручную. В результате вы не можете установить частное поле из подкласса. Таким образом, вы можете: (а) сделать поле защищенным или (б) переопределить класс, добавив код в класс, который объявляет поле.
Что касается Byte Buddy, проще всего использовать Advice:
class ConstructorAdvice {
@Advice.OnMethodExit
static void exit(Advice.Field(value = "foo", readOnly = false) Foo foo) {
foo = new Foo();
}
}
Затем вы примените этот совет ко всем соответствующим конструкторам рассматриваемого класса, используя visit.
Если вам нужно создать много экземпляров
Bar, то почему это статический класс? Такие хаки, какByteBuddy, никогда не должны быть вашей первой мыслью. Почему нельзя сделать это через деривацию?