2

here is my example classes, i want get y and z fields by using reflection in this line (Field[] Fields = forName.getDeclaredFields();) am getting empty array. if y and z or not part of class structure then in which part they belong

package test;

import java.lang.reflect.Field;

public class Reflection {

    static ClassLoader classLoader = null;

    public static void main(String[] args) {
        classLoader = Reflection.class.getClassLoader();
        Reflection r = new Reflection();
        r.getAnnClas();
    }

    private void getAnnClas() {
        Class<?> forName = null;
        try {
            forName = classLoader.loadClass("test.Wrirter");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Field[] declaredFields = forName.getDeclaredFields();
        for (Field field : declaredFields) {
            //here i canot find annoumouse calss filed Z
            System.out.println(field.getName());
        }
    }
}

package test;

import java.io.File;
import java.io.FileReader;

public class Wrirter {

    public Cb c= new Cb(10, 20) {
    public int z = 10;
    public int y=120;
       @Override
        public void doSom() {
          super.doSom();
          int cbf = getIntC() + getIntB();
        }
    };

    public Wrirter() {

    }


}

class Cb {

    public int c;
    public int b;

    public Cb(int c, int b) {
        this.c = c;
        this.b = b;
    }

    public void doSom() {

    }

    public int getIntC() {
        return c;
    }

    public int getIntB() {
        return b;
    }

    public int setIntC() {
        return c;
    }

    public int setIntB() {
        return b;
    }
}
Gaali Prabhakar
  • 583
  • 6
  • 23
  • Related: http://stackoverflow.com/questions/1654889/java-reflection-how-can-i-retrieve-anonymous-inner-classes – aioobe May 11 '15 at 09:37
  • It's not possible I guess. Convert `y` & `z` to instance variable. Then try to do it. – Kartic May 11 '15 at 09:58

2 Answers2

5

You need to operate on the anonymous class, not on the enclosing outer one.

Find below an stripped down example to demonstrate the principle

// the outer class type
Class<?> forName = Wrirter.class;

// instance to investigate
Wrirter outerClass = new Wrirter();

// call the method which create an object of the anonymous class
outerClass.ann();

// get the field which holds a reference to the anonymous class
Field fieldAnonymousClass = forName.getDeclaredField("c");

// get the reference to the anonymous class
Object instanceAnonymousClass = fieldAnonymousClass.get(outerClass);

// get the class type of the anonymous class
Class anonymousClassType = instanceAnonymousClass.getClass();
System.out.println("anonymous class name: " + anonymousClassType.getName());

// get the declared fields of the anonymous class
Field[] declaredFields = anonymousClassType.getDeclaredFields();
for (Field field : declaredFields) {
    if (field.getType() == int.class) {
        // print the field name and its value
        System.out.printf("name: %s  value: %s%n",
                field.getName(),
                field.getInt(instanceAnonymousClass)
        );
    }
}

output

anonymous class name: Wrirter$1
name: y  value: 10
name: z  value: 20


edit Get the field names of the anonymous class without an object reference.

// assuming you have already the anonymous class name
Class<?> anonymousClassType = Class.forName("Wrirter$1");

// get the declared fields of the anonymous class
Field[] declaredFields = anonymousClassType.getDeclaredFields();
for (Field field : declaredFields) {
        System.out.printf("type: %s  name: %s%n",
                field.getType(),
                field.getName()
        );
}

output

type: int  name: y
type: int  name: z


edit 2 Find below a snippet how to get the class names referenced in the constant pool of a class using Javassist.

ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("Wrirter");
ConstPool classConstantPool = cc.getClassFile().getConstPool();
for (String className : (Set<String>) classConstantPool.getClassNames()) {
    System.out.println("className = " + className);
}

output

className = java/lang/Object
className = Wrirter$1
className = Wrirter
SubOptimal
  • 22,518
  • 3
  • 53
  • 69
  • Thank you so much for replay . please check my updated code and in my situation i can't create Wrirter outerClass = new Wrirter(); and i dont need values i just declared fields – Gaali Prabhakar May 11 '15 at 10:37
  • @user99370 I added a second example. – SubOptimal May 11 '15 at 10:58
  • in my case i get lot of will classes will load but how do i know that class has anonymous classes or not – Gaali Prabhakar May 11 '15 at 11:12
  • @user99370 It depends on your use case. Possible solutions might be: traverse through the Jar file for `YourClass$*` class names, trial-and-error for `YourClass$*` class names, using a bytecode manipulation framework to read the `constant pool` of `YourClass` and there for sure other possibilities. – SubOptimal May 11 '15 at 12:25
  • @user99370 I add a small example how to retrieve the name of referenced classes from the constant pool. – SubOptimal May 11 '15 at 12:59
-1

That's not possible. y and z are not part of the class structure.

BetaRide
  • 16,207
  • 29
  • 99
  • 177