无法调用方法,即使它是公开的

时间:2017-06-01 10:33:59

标签: java reflection

这是我的代码。 它抛出

  

无法访问类sun.management.ClassLoadingImpl的成员   修饰语“public”

我首先反映方法,然后调用它。如您所见,getObjectName是一个公共方法,但为什么我不能调用它?

我认为原始代码很混乱,我在这里粘贴一个明确的代码:

public class App {
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
        Object bean = ManagementFactory.getClassLoadingMXBean();
        Method[] methods = bean.getClass().getMethods();
        for (Method method : methods) {
            if (method.getName().equals("getObjectName")) {
                System.out.println(method.getName() + ":" + method.invoke(bean).toString());
            }
        }
    }
}

下面是旧的......

import java.lang.management.ManagementFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Hello world!
 */
public class App {
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
        Method[] methods = ManagementFactory.class.getMethods();
        System.out.println(ManagementFactory.getClassLoadingMXBean().getObjectName());
        for (Method method : methods) {
            if (method.getName().startsWith("get") && method.getName().endsWith("Bean")) {
                System.out.println(method.getName());
                Object bean = method.invoke(null);
                printBean(bean);
            }
        }
    }

    private static void printBean(Object bean) throws InvocationTargetException, IllegalAccessException {
        Method[] methods = bean.getClass().getMethods();
        for (Method method : methods) {
            if (method.getName().startsWith("get")) {
                System.out.println(method.getName());
                System.out.println(method.getName() + ":" + method.invoke(bean).toString());
            }
        }
    }
}

2 个答案:

答案 0 :(得分:3)

由于类不是public,因此无法传递bean实例来调用该方法。您应首先检查课程的可见性:

if (!Modifier.isPublic(bean.getClass().getModifiers())) {
    System.out.println(bean + " is not public");
    return;
}

另一种可能性是将方法设置为可访问:

method.setAccessible(true);

答案 1 :(得分:0)

当您在特定val r1 = spark.sparkContext.parallelize(1 to 5) val r2 = spark.sparkContext.parallelize(5 to 10) val r3 = spark.sparkContext.parallelize(10 to 15) val list = ListBuffer(r1,r2,r3) list.reduce(_ union _).collect().foreach(println) 个实例上致电getMethod[s]时,如Class,您可能会获得bean.getClass()不是Method的{​​{1}}个实例,因此不允许调用它们,即使这些方法实际上是覆盖/实现getDeclaringClass()类或接口的public方法。

public就是这种情况,可以在从声明界面获取public时调用。

getObjectName

但是,当然,这没有优势

Method

如果要动态收集属性,则应使用Object bean = ManagementFactory.getClassLoadingMXBean(); Method method = ClassLoadingMXBean.class.getMethod("getObjectName"); System.out.println(method.getName()+": "+method.invoke(bean).toString()); ,其目的仅限于此目的:

ClassLoadingMXBean bean = ManagementFactory.getClassLoadingMXBean();
System.out.println("getObjectName: "+bean.getObjectName());

此查询甚至不需要MBeanInfo个实例,因为您可以将ClassLoadingMXBean bean = ManagementFactory.getClassLoadingMXBean(); final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); MBeanAttributeInfo[] attr = mBeanServer.getMBeanInfo(bean.getObjectName()).getAttributes(); String[] attrNames = new String[attr.length]; for(int ix=0; ix<attr.length; ix++) attrNames[ix] = attr[ix].getName(); for(Attribute a: mBeanServer.getAttributes(bean.getObjectName(), attrNames).asList()) System.out.println(a.getName()+": "+a.getValue()); 替换为bean的结果。