如何从现场上课?

时间:2016-02-27 15:41:09

标签: java class reflection field

我试图通过反射接收类字段值。但是当我调用我的代码时,我收到异常:IllegalArgumentException:无法将 class field field 设置为java.lang.Class。 (我是从javaagent打来的电话)

我的代码:

 private static Class<?> GetInstance(Class<?> clz) throws NoSuchFieldException, IllegalAccessException {
    Class<?> clazz1 = null;
    Field f = clz.getDeclaredField("INSTANCE");
    f.setAccessible(true);
    clazz1 = f.get(clz).getClass();
    return clazz1;
}

private static Class GetClassLoader(Class<?> clz) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
    Field f = clz.getDeclaredField("classLoader");
    f.setAccessible(true);
    Class cls = f.get(clz).getClass();
    return cls;
}

public static void agentmain(String agentArgs, Instrumentation inst){
    try{
        inst.addTransformer(new ClientTransfomer());

        Class<?> FMLDeobfuscatingRemapper = null;
        Class<?> InstanceClass;
        Class<?>[] classes = inst.getAllLoadedClasses();
        for(int i = 0;i < classes.length;i++){
            if(classes[i].getName().contains("cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper")){
                FMLDeobfuscatingRemapper = classes[i];
            }

        }

        Class<?> instance = GetInstance(FMLDeobfuscatingRemapper);
        Class cloader = GetClassLoader(instance);

        Method m = cloader.getDeclaredMethod("findClass");
        m.setAccessible(true);
        m.invoke(null, "net.minecraft.client.entity.EntityClientPlayerMP");

    }catch (Exception e){


    }

3 个答案:

答案 0 :(得分:1)

  

如何从现场上课?

fieldValue.getClass()。不需要反思。

你的代码毫无意义。

  • 您有一个名为GetInstance()的方法,它返回Class,而不是实例。您需要将此方法的返回值更改为Object并删除其中的getClass()调用。
  • 您有一个名为GetClassLoader()的方法,它返回Class,而不是ClassLoader。您需要将此方法的返回类型更改为ClassLoader,并删除其中的getClass()调用。

  • 然后你反思性地将这个对象视为 一个ClassLoader,而不是它,并试图在其上调用findClass()。< / p>

但是,一旦你拥有实例,我就看不到在这里使用反射的必要性:你可以直接调用getClass().getClassLoader().findClass()

答案 1 :(得分:0)

你的意思是什么?

    public class One {
        public Two two = new Two();
    }

    public class Two {
    public void hello(){
        System.out.println("hello");
    }
}



    public static void main(String[] args) {
      public static void main(String[] args) {
        One one = new One();
        Class<?> clazz = one.getClass();
        try {
            Field twoField = clazz.getField("two");
            twoField.setAccessible(true);
            Class<?> twoClazz =Class.forName(twoField.getType().getName());

            Method method = twoClazz.getMethod("hello", null);

            method.invoke(twoClazz.newInstance(), null);
        } catch (NoSuchFieldException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException | InstantiationException e) {
            e.printStackTrace();
        }
    }
}

答案 2 :(得分:0)

使用如下所示的getType():

clz.getDeclaredField("fieldName").getType()