在 Java 中通过引用获取对象

Getting an Object by reference in Java

这个网站的新手,很高兴分享我的第一个问题:)

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

我有 2 java 个应用程序:

  1. 逻辑应用程序(发生所有重负载的地方)
  2. 已检测的应用程序(应用程序已检测到 运行ning 游戏)

我对这 2 个应用程序所做的是使用 Instrumented Application 从游戏中提取信息,然后将其发送到逻辑应用程序。 information/data 的提取是通过 Java 反射 API 完成的。然后在提取信息后,通过 RMI 将其发送到逻辑应用程序(更多内容见下文)。

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

我在两者之间传输data/information的方式是通过RMI(远程方法调用)。 说明:Logic 应用程序在 Instrumented App 调用 getter 方法,该方法使用反射 API 从它被检测到的游戏中获取字段值并 return 它。

现在你们已经了解了我基本上在做什么,现在是我被迷惑了很长一段时间的挑战。

问题:

大多数由反射 return 编辑的字段值都是可序列化的,因此它们可以毫无问题地通过 RMI。但是,有些是不可序列化的对象,例如“Item”。 “Item”是一个对象,它包含 3 个值:ID、名称、数量。所以我的想法是制作一个包装器并发送包装器,这样问题就解决了吗?但是没有,另一个挑战突然出现了。

突然出现的挑战是:如果我需要知道我在另一个时间取出的对象“Item”的数量怎么办?如果我的整个事情是 1 个应用程序,我会使用反射 API 通过以下方式使用对象获取字段: getClassLoader().loadClass("ItemClass").getDeclaredField("Item").get(ObjectThatIPreviouslyFetched); 但是由于我必须将对象转移到逻辑应用程序,我无法将对象本身“项目”转移,所以我无法 return 到该对象并获得更新的信息,除非我再次查找该对象浪费资源并使我的整个过程变慢。

应用程序是这样工作的:

Instrumented App -> Reflection -> Game -> Field Value (Object called Item) -> Wrapper -> RMI -> Logic Application(对象信息已发送,但对象本身由于不可序列化而无法发送)

问题摘要(使用上面的指针):如何取回对象(项目)以便使用反射获取有关它的更新信息。

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

   /**
    *
    * @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;
   } 

此方法可在逻辑应用程序中找到,并将 Instrumented 应用程序附加到 运行ning 游戏:

    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 在内存中注册它们,然后使用地址获取对象。尽管您稍后必须释放它,否则它会变成焦土。