在Java中通过引用获取对象



本网站新手,很高兴能分享我的第一个问题:(

好的,我将解释我目前的设置,以便更好地理解我的问题。

我有两个java应用程序:

  1. 逻辑应用程序(所有重载都发生的地方(
  2. 插入指令的应用程序(插入正在运行的游戏中的应用程序(

我对这两个应用程序所做的是使用Instrumented应用程序从游戏中提取信息,然后将其发送到逻辑应用程序。信息/数据的提取是通过Java Reflection API完成的。然后,在提取信息后,它通过RMI发送到逻辑应用程序(下面将对此进行详细介绍(。

我之所以有2个应用程序而不是1个,是因为游戏在Java 7(旧游戏(上运行,所以Instrumented应用程序在Java 7上运行,我可以在任何我想要的Java版本上运行Logic应用程序。

我在2之间传输数据/信息的方式是通过RMI(远程方法调用(。说明:Logic应用程序在Instrumented应用程序中调用getter方法,该方法使用Reflection API从它插入的游戏中获取字段值并返回

现在,你们已经明白了我基本上在做什么,现在,我被欺骗了很长一段时间的挑战来了。

问题:

反射返回的大多数字段值都是可序列化的,因此它们可以顺利通过RMI。但是,有些是不可序列化的对象,例如";项目";。"项目";是一个对象,它包含3个值:ID、名称和数量。所以我的想法是制作一个包装并发送包装,问题就会得到解决,对吧?但没有,又出现了一个挑战。

突然出现的挑战是:如果我需要知道物体的数量,该怎么办;项目";我在另一个时间退出的?如果我的全部是1个应用程序,我会使用Reflection API通过以下方式获得使用Object的Field:getClassLoader().loadClass("ItemClass").getDeclaredField("Item").get(ObjectThatIPreviouslyFetched);但是由于我必须将对象转移到逻辑应用程序,所以我不能将对象本身"转移"到逻辑应用;项目";所以我没有办法返回到那个对象并获得更新的信息,除非我再次寻找那个对象,这是浪费资源,使我的整个过程更慢。

应用程序是这样工作的:

仪表化应用程序->反射->游戏->字段值(称为Item的对象(->包装器->RMI->逻辑应用程序(发送了对象信息,但由于对象本身不可序列化,因此无法发送(

问题摘要(使用上面的指针(:我如何才能取回Object(Item(,以便使用Reflection获得有关它的更新信息。

这是我用来获取字段值(对象(的方法:

/**
*
* @param params owner;fieldName;multiplier
* @param object null if static
* @return returns the value of the object provided.
*/
public Object getFieldValue(String params, Object object) {
String[] paramsSplit = params.split(";");
try {
Class<?> clazz = classLoader.loadClass(paramsSplit[0]);
Field field = clazz.getDeclaredField(paramsSplit[1]);
field.setAccessible(true);
Object o = field.get(object);
if(!paramsSplit[2].equals("0")) return getMultipliedValue((Number) o,paramsSplit[2]);
else return o;
} catch (IllegalAccessException | NoSuchFieldError | ClassNotFoundException | NoSuchFieldException e) {
e.printStackTrace();
}
return null;
} 

这种方法可以在逻辑应用程序中找到,它将仪器应用程序连接到正在运行的游戏:

public void inject() {
VirtualMachine vm = null;
try {
vm = VirtualMachine.attach(String.valueOf(pid));
vm.loadAgent(Info.baseLocation());
} catch (AttachNotSupportedException | IOException |
AgentLoadException | AgentInitializationException e) {
e.printStackTrace();
} finally {
try {
if(vm != null) vm.detach();
} catch (IOException e) {
e.printStackTrace();
}
}
}

我希望一切都可以理解,我不是英国人,所以如果出现问题,我道歉。

谢谢!

没有"对";回答这个问题。

我开始制作一个存储对象的地图,并为每个对象指定一个唯一的键。然后,我通过RMI发送对象的唯一密钥,现在我可以使用唯一密钥获取对象,并随时发送对象的内部信息。

如果对象没有循环引用,请尝试JSON。建议使用GSON。

另一种方法是使用UnSafe将它们注册到内存中,然后使用地址获取对象。尽管你必须稍后释放它,否则它会烧焦的大地。

最新更新