shadow
shadow

Reputation: 94

how to get the class' members from a class file

if there is a class file called "demo.class", is it possible to analysis the file without run it by VM,and get its members' message, such as attributes' name,methods' name and fields' type?

if it do,please give me any advice for how to start my work,thank you!

Upvotes: 2

Views: 203

Answers (3)

achan1989
achan1989

Reputation: 101

you can use Java disassembler 'javap command'

suppose your class files are located in bin folder & path is "D:\dev\jdk_1.06\bin" then 1.open command prompt 2.change directory to above mentioned path. 3.type java javaclassfilename for example: for hello.class use command javap hello

Upvotes: 0

John Farrelly
John Farrelly

Reputation: 7459

If you only have the class file (and can't load it because it's not on the classpath or you don't want to load it), you can inspect it using Apache Commons Byte Code Engineering Library

ClassParser parser=new ClassParser(getClass().getResourceAsStream("/my/package/MyClass.class"), "MyClass.class");
JavaClass javaClass=parser.parse();
javaClass.getMethods(); // Get whatever info you need

Upvotes: 1

RamonBoza
RamonBoza

Reputation: 9038

You can use reflection

http://docs.oracle.com/javase/tutorial/reflect/class/classMembers.html

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Member;
import static java.lang.System.out;

enum ClassMember { CONSTRUCTOR, FIELD, METHOD, CLASS, ALL }

public class ClassSpy {
    public static void main(String... args) {
    try {
        Class<?> c = Class.forName(args[0]);
        out.format("Class:%n  %s%n%n", c.getCanonicalName());

        Package p = c.getPackage();
        out.format("Package:%n  %s%n%n",
               (p != null ? p.getName() : "-- No Package --"));

        for (int i = 1; i < args.length; i++) {
        switch (ClassMember.valueOf(args[i])) {
        case CONSTRUCTOR:
            printMembers(c.getConstructors(), "Constructor");
            break;
        case FIELD:
            printMembers(c.getFields(), "Fields");
            break;
        case METHOD:
            printMembers(c.getMethods(), "Methods");
            break;
        case CLASS:
            printClasses(c);
            break;
        case ALL:
            printMembers(c.getConstructors(), "Constuctors");
            printMembers(c.getFields(), "Fields");
            printMembers(c.getMethods(), "Methods");
            printClasses(c);
            break;
        default:
            assert false;
        }
        }

        // production code should handle these exceptions more gracefully
    } catch (ClassNotFoundException x) {
        x.printStackTrace();
    }
    }

    private static void printMembers(Member[] mbrs, String s) {
    out.format("%s:%n", s);
    for (Member mbr : mbrs) {
        if (mbr instanceof Field)
        out.format("  %s%n", ((Field)mbr).toGenericString());
        else if (mbr instanceof Constructor)
        out.format("  %s%n", ((Constructor)mbr).toGenericString());
        else if (mbr instanceof Method)
        out.format("  %s%n", ((Method)mbr).toGenericString());
    }
    if (mbrs.length == 0)
        out.format("  -- No %s --%n", s);
    out.format("%n");
    }

    private static void printClasses(Class<?> c) {
    out.format("Classes:%n");
    Class<?>[] clss = c.getClasses();
    for (Class<?> cls : clss)
        out.format("  %s%n", cls.getCanonicalName());
    if (clss.length == 0)
        out.format("  -- No member interfaces, classes, or enums --%n");
    out.format("%n");
    }
}

Upvotes: 3

Related Questions