返回顶部
首页 > 资讯 > 精选 >怎么找到真正的public方法
  • 202
分享到

怎么找到真正的public方法

2023-06-02 14:06:44 202人浏览 薄情痞子
摘要

小编给大家分享一下怎么找到真正的public方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!摘要Class.getMethods() 能返回 class 及父类

小编给大家分享一下怎么找到真正的public方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

摘要Class.getMethods() 能返回 class 及父类中所有 public方法。然而,这些方法并不一定能被调用,比如在 private inner class 或 lambda 表达式中声明的方法。这篇文章会介绍如何找到所有真正的 public 方法。

昨天,我试图找出某个未知对象的所有 public 方法。这件事应该很容易,用getClass()import java.lang.reflect.*;
import java.util.*;
public class ReflectionPuzzle {
 public static void main(String... args) {
   Collection<String> names = new ArrayList<>();
   Collections.addAll(names, "Goetz", "Marks", "Rose");
   printSize(names);
   printSize(Arrays.asList("Goetz", "Marks", "Rose"));
   printSize(List.of("Goetz", "Marks", "Rose"));
   printSize(Collections.unmodifiableCollection(names));
 }
 private static void printSize(Collection<?> col) {
   System.out.println("Size of " + col.getClass().getName());
   try {
     Method sizeMethod = col.getClass().getMethod("size");
     System.out.println(sizeMethod.invoke(col));
   } catch (ReflectiveOperationException e) {
     System.err.println(e);
   }
 }
}

上面的程序运行结果如下:

Size of java.util.ArrayList
3
Size of java.util.Arrays$ArrayList
java.lang.IllegalAccessException: class ReflectionPuzzle cannot
access a member of class java.util.Arrays$ArrayList (in module
java.base) with modifiers "public"
Size of java.util.ImmutableCollections$ListN
java.lang.IllegalAccessException: class ReflectionPuzzle cannot
access a member of class java.util.ImmutableCollections$ListN (in
module java.base) with modifiers "public"
Size of java.util.Collections$UnmodifiableCollection
java.lang.IllegalAccessException: class ReflectionPuzzle cannot
access a member of class
java.util.Collections$UnmodifiableCollection (in module
java.base) with modifiers "public"

只有ArrayList执行printSize()时能得到结果。虽然package problem;
public interface A {
 CharSequence foo();
}
package problem;
public interface B {
 java.io.Serializable foo();
}

接下来,我们在另一个 packagepackage problem.inner;
import problem.*;
public class Hidden {
 public static A getPrivateInnerClass() {
   return new C();
 }
 private static class C implements A, B {
   public String foo() {
     return "Hello World";
   }
   public String bar() {
     return "Should not be visible";
   }
 }
 public static A getMethodClass() {
   class D implements A {
     public CharSequence foo() {
       return "inside method";
     }
   }
   return new D();
 }
 public static A getLambda() {
   return () -> "Hello Lambert";
 }
}

下面这个示例展示了如何用普通的反射调用import problem.*;
import problem.inner.*;

import java.lang.reflect.*;
import java.util.stream.*;
public class TestPlainReflection {
 public static void main(String... args) {
   System.out.println("Testing private inner class");
   test(Hidden.getPrivateInnerClass());
   System.out.println();
   System.out.println("Testing method inner class");
   test(Hidden.getMethodClass());
   System.out.println();
   System.out.println("Testing lambda");
   test(Hidden.getLambda());
 }
 private static void test(A a) {
   Stream.of(a.getClass().getMethods())
       .forEach(System.out::println);
   printMethodResult(a, "foo");
   printMethodResult(a, "bar");
 }
 private static void printMethodResult(Object o, String name) {
   try {
     Method method = o.getClass().getMethod(name);
     System.out.println(method.invoke(o));
   } catch (NoSuchMethodException e) {
     System.out.println("Method " + name + "() not found");
   } catch (IllegalAccessException e) {
     System.out.println("Illegal to call " + name + "()");
   } catch (InvocationTargetException e) {
     throw new IllegalStateException(e.getCause());
   }
 }
}

结果同样不理想。通过Testing private inner class
public CharSequence problem.inner.Hidden$C.foo()
public java.io.Serializable problem.inner.Hidden$C.foo()
public String problem.inner.Hidden$C.foo()
public String problem.inner.Hidden$C.bar()
public Class Object.getClass()
public boolean Object.equals(Object)
public int Object.hashCode()
public String Object.toString()
public void Object.wait() throws InterruptedException
public void Object.wait(long) throws InterruptedException
public void Object.wait(long,int) throws InterruptedException
public void Object.notify()
public void Object.notifyAll()
Illegal to call foo()
Illegal to call bar()
Testing method inner class
public CharSequence problem.inner.Hidden$1D.foo()
public Class Object.getClass()
public boolean Object.equals(Object)
public int Object.hashCode()
public String Object.toString()
public void Object.wait() throws InterruptedException
public void Object.wait(long) throws InterruptedException
public void Object.wait(long,int) throws InterruptedException
public void Object.notify()
public void Object.notifyAll()
Illegal to call foo()
Method bar() not found
Testing lambda
public CharSequence problem.inner.Hidden$$Lambda$23/0x67840.foo()
public Class Object.getClass()
public boolean Object.equals(Object)
public int Object.hashCode()
public String Object.toString()
public void Object.wait() throws InterruptedException
public void Object.wait(long) throws InterruptedException
public void Object.wait(long,int) throws InterruptedException
public void Object.notify()
public void Object.notifyAll()
Illegal to call foo()
Method bar() not found

注意:我们无法通过这些对象调用import java.lang.reflect.*;
import java.util.*;
import java.util.stream.*;
public class Reflections {
 public static Optional<Method> getTrulyPublicMethod(
     Class<?> clazz, String name, Class<?>... paramTypes) {
   return getTrulyPublicMethods(clazz)
       .stream()
       .filter(method -> matches(method, name, paramTypes))
       .reduce((m1, m2) -> {
         Class<?> r1 = m1.getReturnType();
         Class<?> r2 = m2.getReturnType();
         return r1 != r2 && r1.isAssignableFrom(r2) ? m2 : m1;
       });
 }
 public static Collection<Method> getTrulyPublicMethods(
     Class<?> clazz) {
   Map<String, Method> result = new HashMap<>();
   findTrulyPublicMethods(clazz, result);
   return List.copyOf(result.values());
 }
 private static void findTrulyPublicMethods(
     Class<?> clazz, Map<String, Method> result) {
   if (clazz == null) return;
   Method[] methods = clazz.getMethods();
   for (Method method : methods) {
     if (isTrulyPublic(method))
       result.putIfAbsent(toString(method), method);
   }
   for (Class<?> intf : clazz.getInterfaces()) {
     findTrulyPublicMethods(intf, result);
   }
   findTrulyPublicMethods(clazz.getSuperclass(), result);
 }
 private static boolean isTrulyPublic(Method method) {
   return Modifier.isPublic(method.getModifiers()
       & method.getDeclarinGClass().getModifiers());
 }
 private static String toString(Method method) {
   String prefix = method.getReturnType().getCanonicalName() +
       method.getName() + " (";
   return Stream.of(method.getParameterTypes())
       .map(Class::getCanonicalName)
       .collect(Collectors.joining(", ",
           prefix, ")"));
 }
 private static boolean matches(
     Method method, String name, Class<?>... paramTypes) {
   return method.getName().equals(name)
       && Arrays.equals(method.getParameterTypes(), paramTypes);
 }
}

可以确定的是,这里没有考虑所有返回类型和一些可能出错的 class 层次结构。但是,这段代码的确通过了我的测试。另外,使用 Optional 要比捕捉异常好。下面是 TestTrulyPublic 实现: 

import problem.*;
import problem.inner.*;
import java.lang.reflect.*;
import java.util.*;
public class TestTrulyPublic {
 public static void main(String... args) throws Exception {
   System.out.println("Testing private inner class");
   test(Hidden.getPrivateInnerClass());
   System.out.println();
   System.out.println("Testing method inner class");
   test(Hidden.getMethodClass());
   System.out.println();
   System.out.println("Testing lambda");
   test(Hidden.getLambda());
 }
 private static void test(A a) {
   Reflections.getTrulyPublicMethods(a.getClass()).forEach(
       System.out::println);
   printMethodResult(a, "foo");
   printMethodResult(a, "bar");
 }
 private static void printMethodResult(
     Object o, String methodName) {
   Optional<Method> method = Reflections.getTrulyPublicMethod(
       o.getClass(), methodName);
   method.map(m -> {
     try {
       System.out.println("m = " + m);
       return m.invoke(o);
     } catch (IllegalAccessException e) {
       throw new IllegalStateException(e);
     } catch (InvocationTargetException e) {
       throw new IllegalStateException(e.getCause());
     }
   }).ifPresentOrElse(System.out::println,
       () -> System.out.println("Method " +
           methodName + "() not found"));
 }
}

运行第二个测试,得到以下输出结果:

Testing private inner classpublic abstract java.io.Serializable problem.B.foo()
public abstract CharSequence problem.A.foo()
public Class Object.getClass()
public boolean Object.equals(Object)
publicint Object.hashCode()
public String Object.toString()
publicvoid Object.wait() throws InterruptedException
publicvoid Object.wait(long) throws InterruptedException
publicvoid Object.wait(long,int) throws InterruptedException
publicvoid Object.notify()
publicvoid Object.notifyAll()
m = public abstract java.io.Serializable problem.B.foo()
Hello World
Method bar() not found
Testing method inner classpublic abstract CharSequence problem.A.foo()
public Class Object.getClass()
public boolean Object.equals(Object)
publicint Object.hashCode()
public String Object.toString()
publicvoid Object.wait() throws InterruptedException
publicvoid Object.wait(long) throws InterruptedException
publicvoid Object.wait(long,int) throws InterruptedException
publicvoid Object.notify()
publicvoid Object.notifyAll()
m = public abstract CharSequence problem.A.foo()
inside methodfunction(){   //外汇跟单www.gendan5.comMethod bar() not found
Testing lambda
public abstract CharSequence problem.A.foo()
public Class Object.getClass()
public boolean Object.equals(Object)
publicint Object.hashCode()
public String Object.toString()
publicvoid Object.wait() throws InterruptedException
publicvoid Object.wait(long) throws InterruptedException
publicvoid Object.wait(long,int) throws InterruptedException
publicvoid Object.notify()
publicvoid Object.notifyAll()
m = public abstract CharSequence problem.A.foo()
Hello Lambert
Method bar() not found

可以看到,现在所有 foo() 调用都成功了,还可以看到这里没有找到 bar() 方法。 

以上是“怎么找到真正的public方法”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: 怎么找到真正的public方法

本文链接: https://lsjlt.com/news/230371.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么找到真正的public方法
    小编给大家分享一下怎么找到真正的public方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!摘要Class.getMethods() 能返回 class 及父类...
    99+
    2023-06-02
  • php找不到include方法怎么办
    本文操作环境:Windows7系统,PHP7.4版,Dell G3电脑。php找不到include方法怎么办?PHP脚本中include文件出错解决方法经常当php页面中利用include, require, require_once包含了...
    99+
    2014-10-11
    php include
  • 找到mysql密码的方法
    这篇文章给大家分享的是有关找到mysql密码的方法的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。找到mysql密码的方法:首先打开Navicat并找到mysql;然后打开mysq...
    99+
    2024-04-02
  • 如果网站用了CDN,我怎么找到它的真实IP
    如果网站使用了CDN(内容分发网络),它的真实IP地址可能会被隐藏起来,因为CDN会通过将网站内容分发到多个服务器上的方式来提高网站...
    99+
    2023-09-09
    网站
  • 找不到mysql.h的解决方法
    小编给大家分享一下找不到mysql.h的解决方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! 找不...
    99+
    2024-04-02
  • 找不到wp config.php的解决方法
    这篇文章主要介绍找不到wp config.php的解决方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!找不到wp config.php的解决办法:1、添加一个“wp-config.php”文件;然后重启一下web服...
    99+
    2023-06-15
  • php domdocument找不到的解决方法
    本篇内容介绍了“php domdocument找不到的解决方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!php domdocument找...
    99+
    2023-06-20
  • java在类中找不到main方法怎么解决
    在Java中,每个独立的程序都需要一个包含main方法的类作为程序的入口点。如果在类中找不到main方法,可以尝试以下解决方法: ...
    99+
    2023-10-24
    java
  • Vue虚拟Dom到真实Dom的转换方法
    这篇文章主要介绍“Vue虚拟Dom到真实Dom的转换方法”,在日常操作中,相信很多人在Vue虚拟Dom到真实Dom的转换方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue虚拟Dom到真实Dom的转换方法...
    99+
    2023-06-20
  • Vista下以真正的管理员登陆的设置方法
    也许你会认为在安装时就为你创建了一个账户就是管理员了,其实这个管理员还是有限制的,也就是有点冒牌,不能完全体现其性能。例:UAC不在多管闲事,因UAC管的是那些不是真正的管理员而是冒牌的管理员,当删除垃圾文件时就会弹出一...
    99+
    2023-05-24
    方法 设置 管理员 Vista
  • SpringAop日志找不到方法的处理
    SpringAop日志找不到方法 错误截图: 显示没有找到该方法,于是我找到对应的类和对应的方法: 这里我用了反射来获取方法名和参数: 错误打印的结果显示方法名获取没有错误,于...
    99+
    2024-04-02
  • 没有找到msvcr100.dll的解决方法
    小编给大家分享一下没有找到msvcr100.dll的解决方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!  没有找到msvcr100.dll怎么办  方法一: ...
    99+
    2023-06-06
  • libmysqlclient.so.10无法找到该怎么办
    这篇文章给大家介绍libmysqlclient.so.10无法找到该怎么办,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。libmysqlclient.so.10 is needed by MySQL-python-0....
    99+
    2023-06-13
  • 无法找到Package Proftpd怎么解决
    这篇文章给大家介绍无法找到Package Proftpd怎么解决,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。ProFTPD:一个Unix平台上或是类Unix平台上(如Linux, FreeBSD等)的FTP服务器程序...
    99+
    2023-06-16
  • windows找不到文件确定是否正确怎么解决
    本文小编为大家详细介绍“windows找不到文件确定是否正确怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“windows找不到文件确定是否正确怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。win...
    99+
    2023-07-01
  • 阿里云服务器找不到了怎么解决方法
    检查文件路径是否正确:确保你正在访问的文件路径是正确的。如果你不确定文件的路径,请使用绝对路径或相对路径来访问它。 检查文件是否被删除或移动过:如果你删除或移动了文件,可能会导致阿里云服务器上的文件列表丢失。如果你想要查找已经被删除或移动...
    99+
    2023-10-28
    找不到 阿里 解决方法
  • php中找不到对象的解决方法
    小编给大家分享一下php中找不到对象的解决方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!php找不到对象的解决办法:首先在运行里选择web服务器设置;然后点外...
    99+
    2023-06-15
  • Win10找不到Documents and Settings的解决方法
    在Windows 10中,"Documents and Settings"文件夹被替换为"C:\Users"文件夹。您可以按照以下步...
    99+
    2023-09-17
    win10
  • IDEA找不到Database的完美解决方法
    目录第一步:在idea中找到View->Tool Windows第二步:找到File->Settings第三步:找到plugins,然后在marketplace输入data,找到database naviga...
    99+
    2023-05-12
    idea找不到database idea没有database选项 idea找不到database选项
  • pycharm找不到解释器的解决方法
    小编给大家分享一下pycharm找不到解释器的解决方法,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!解决方法:1、打开磁盘,直接搜索python.exe文件,获取该文件的路径;2、打开pycharm软件,依次点击“File...
    99+
    2023-06-08
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作