因为private方法只能在类的内部调用... 外部都没办法...

解决方案 »

  1.   

    不会啊,getDeclaredMethods是可以获取到private方法的。但是如果希望通过invoke执行的话,只需要setAccessible(true);就可以了。你或许可以把你的完整代码发上来大家看看。
      

  2.   

    当然可以,除非private方法不在当前类,在父类的方法是获取不到的public class TestReflect { /**
     * @param args
     */
    public static void main(String[] args) {
    Class<?> clazz = TestReflect.class;
    Method[] methods = clazz.getDeclaredMethods();
    for (Method method : methods) {
    System.out.println(method.getName());
    }
    } public void publicMethod() { } protected void protectedMethod() { } private void privateMethod() { }}写了个简单的测试方法,你看看
      

  3.   

    完整的代码如下:import java.lang.reflect.Method;public class ClassTest {
    public static void main(String[] args) throws Exception {
    Class<?> clazz = Class.forName("android.widget.AbsListView");
    Method[] allMethods = clazz.getDeclaredMethods(); String s;
    StringBuilder builder_publicMethods = new StringBuilder();
    StringBuilder builder_privateMethods = new StringBuilder();
    StringBuilder builder_protectedMethods = new StringBuilder(); for (Method method : allMethods) {

    method.setAccessible(true);
    s = method.toString().replace("android.widget.AbsListView" + ".",
    "")
    + "\n";
    if (s.startsWith("public")) {
    builder_publicMethods.append(s);
    } else if (s.startsWith("private")) {
    builder_privateMethods.append(s);
    } else if (s.startsWith("protected")) {
    builder_protectedMethods.append(s);
    }

    } System.out
    .printf("public方法:\n\n%s\n\n--------------------\n\nprivate方法:\n\n%s\n\n--------------------\n\nprotected方法:\n\n%s\n",
    builder_publicMethods.toString(),
    builder_privateMethods.toString(),
    builder_protectedMethods.toString());

    }
    }是Java Application项目,需要导入android.jar包。
      

  4.   


    你说得对,因为我反射的类不是当前类,所以获取不到私有方法。那怎么获取非当前类的私有方法呢?对父类遍历,直到Object
      

  5.   


    你说得对,因为我反射的类不是当前类,所以获取不到私有方法。那怎么获取非当前类的私有方法呢?对父类遍历,直到Object可是要遍历的类是动态加载的。
      

  6.   


    你说得对,因为我反射的类不是当前类,所以获取不到私有方法。那怎么获取非当前类的私有方法呢?
    你加载的哪个类就反射哪个类的方法,跟当前类有什么关系:
    class PrivateMethod{
    private String getName(){
    return "PrivateMethod";
    }
    public class ClassTest {
    public static void main(String[] args) throws Exception {
    Class<?> clazz0 = Class.forName("learning.PrivateMethod");
    Method[] methods = clazz0.getDeclaredMethods();

    for (Method method : methods) {
    method.setAccessible(true);
    System.out.println(method.toString());
    }
    }
    private java.lang.String learning.PrivateMethod.getName()
    }
    楼主把这个类的源码贴出来看看吧,尤其是私有方法那部分
      

  7.   


    你说得对,因为我反射的类不是当前类,所以获取不到私有方法。那怎么获取非当前类的私有方法呢?
    你加载的哪个类就反射哪个类的方法,跟当前类有什么关系:
    class PrivateMethod{
    private String getName(){
    return "PrivateMethod";
    }
    public class ClassTest {
    public static void main(String[] args) throws Exception {
    Class<?> clazz0 = Class.forName("learning.PrivateMethod");
    Method[] methods = clazz0.getDeclaredMethods();

    for (Method method : methods) {
    method.setAccessible(true);
    System.out.println(method.toString());
    }
    }
    private java.lang.String learning.PrivateMethod.getName()
    }
    楼主把这个类的源码贴出来看看吧,尤其是私有方法那部分
    反射非当前类,不能获取private方法,但我要看到。这个AbsListView的私有方法N多,没必要贴。
      

  8.   


    你说得对,因为我反射的类不是当前类,所以获取不到私有方法。那怎么获取非当前类的私有方法呢?
    你加载的哪个类就反射哪个类的方法,跟当前类有什么关系:
    class PrivateMethod{
    private String getName(){
    return "PrivateMethod";
    }
    public class ClassTest {
    public static void main(String[] args) throws Exception {
    Class<?> clazz0 = Class.forName("learning.PrivateMethod");
    Method[] methods = clazz0.getDeclaredMethods();

    for (Method method : methods) {
    method.setAccessible(true);
    System.out.println(method.toString());
    }
    }
    private java.lang.String learning.PrivateMethod.getName()楼主把这个类的源码贴出来看看吧,尤其是私有方法那部分
    反射非当前类,不能获取private方法,但我要看到。这个AbsListView的私有方法N多,没必要贴。你仔细看我反射的类为PrivateMethod,不是当前类,最后的输出为private java.lang.String learning.PrivateMethod.getName()
      

  9.   


    你说得对,因为我反射的类不是当前类,所以获取不到私有方法。那怎么获取非当前类的私有方法呢?对父类遍历,直到Object可是要遍历的类是动态加载的。什么意思?父类肯定在子类之前加载啊
      

  10.   

    我的意思是说,目前的需求不适合用继承父类然后反射父类的方法。我要做一个独立的反射工具,当用户输入他们想了解的某个类,用字符串的形式输入,反射工具用Class.forName去加载,然后把这个类的所有方法都列出来。
      

  11.   

    测试出来了,下面的代码符合需求(需要导入android.jar包):import java.lang.reflect.Method;
    import java.lang.reflect.Constructor;
    import java.util.Scanner;
    import android.content.Context;public class ClassTest {

    private static final String regStr="(?<=\\s)(\\w+\\.)+(?=\\w+\\s|\\w+\\(|\\w+\\[)";

    public static void main(final String[] args) throws Exception {
    Scanner scanner=new Scanner(System.in);
    System.out.println("请输入: 包名.类名");
    final String className=scanner.nextLine();
    scanner.close();
    Thread thread1 = new Thread() {
    @Override
    public void run() {
    try {
    reflect1(className);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    };
    thread1.start();
    thread1.join(); new Thread() {
    @Override
    public void run() {
    try {
    reflect2(className);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }.start();
    } private static void reflect1(String className) throws Exception {
    Constructor<?> cts = Class.forName(className).getConstructor(
    Context.class);
    cts.setAccessible(true); Method[] methods1 = cts.getClass().getDeclaredMethods(); String s;
    StringBuilder builder_publicMethods = new StringBuilder();
    StringBuilder builder_privateMethods = new StringBuilder(); for (Method method : methods1) {
    s = method.toString().replaceAll(regStr, "")+"\n";
    if (s.startsWith("public")) {
    builder_publicMethods.append(s);
    } else if (s.startsWith("private")) {
    builder_privateMethods.append(s);
    }
    }
    System.out
    .printf("\n\npublic方法:\n\n%s\n--------------------\n\nprivate方法:\n\n%s\n--------------------\n\n",
    builder_publicMethods.toString(),
    builder_privateMethods.toString());
    } private static void reflect2(String className) throws Exception {
    Method[] methods2 = Class.forName(className).getDeclaredMethods();
    String s;
    StringBuilder builder_protectedMethods = new StringBuilder();
    for (Method method : methods2) {
    s = method.toString().replaceAll(regStr, "")+"\n";
    if (s.startsWith("protected")) {
    builder_protectedMethods.append(s);
    }
    }
    System.out.printf("protected方法:\n\n%s\n",
    builder_protectedMethods.toString());
    }
    }关键语句在:
    ①Constructor<?> cts = Class.forName(className).getConstructor(
    Context.class);
    cts.setAccessible(true);
    Method[] methods1 = cts.getClass().getDeclaredMethods();这样能获取public和private方法,但获取不到protected方法;
    ②Method[] methods2 = Class.forName(className).getDeclaredMethods();则能够获取到protected方法。之所以写成两个线程去调用,是因为:
    如果只是在主线程调用Class.forName,那么在第一次Class.forName之后,此Class将一直缓存在主线程中;cts.setAccessible(true)作用于此缓存的Class对象,虽然能获取到它的public和private方法,但获取不到protected方法。如果想获取protected方法,即使后续的代码写成cts.setAccessible(false)也没用;甚至重新Class.forName,它也只是调用当前的Class缓存对象,依旧获取不到。也就是说下面注释的代码有问题:Constructor<?> cts = Class.forName(className).getConstructor(
    Context.class);
    cts.setAccessible(true);Method[] methods1 = cts.getClass().getDeclaredMethods();  //可以获取到public和private方法//cts.setAccessible(false);
    //Method[] methods2 = cts.getClass().getDeclaredMethods();  //获取不到protected方法//-----------------//Class<?> clazz = Class.forName(className);  //已有此Class缓存,直接使用此缓存
    //Method[] methods2 = clazz.getDeclaredMethods();  //依旧获取不到protected方法而将前后两次Class.forName写在不同子线程里,那么两次缓存的Class储存在各自所在的子线程,不会相互影响。
    我也不是很清楚为什么会这样,待研究。
      

  12.   

    其实我还是错了,因为:Constructor<?> cts = Class.forName(className).getConstructor(
    Context.class);
    Class<?> clazz1=cts.getClass();
    此时获取的clazz1是java.lang.reflect.Constructor类型!而不是参数className对应的Class!所以cts之后的所有语句,其实都在反射这个Constructor。整体思路错误。