我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么找到真正的public方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么找到真正的public方法

小编给大家分享一下怎么找到真正的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方法”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么找到真正的public方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么找到真正的public方法

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

php找不到include方法怎么办

php找不到include方法的解决办法:1、检查include文件的位置是否正确;2、检测被包含的文件读权限是否打开;3、检测被包含的文件路径上的每个目录的x权限是否打开即可。
2014-10-11

如果网站用了CDN,我怎么找到它的真实IP

如果网站使用了CDN(内容分发网络),它的真实IP地址可能会被隐藏起来,因为CDN会通过将网站内容分发到多个服务器上的方式来提高网站的访问速度和可靠性。然而,你可以尝试以下几种方法来找到网站的真实IP地址:1. 使用在线工具:有一些在线工具
2023-09-09

java在类中找不到main方法怎么解决

在Java中,每个独立的程序都需要一个包含main方法的类作为程序的入口点。如果在类中找不到main方法,可以尝试以下解决方法:确保类名和文件名匹配:在Java中,类名必须与文件名完全匹配,包括大小写。如果类名和文件名不匹配,Java编译器
2023-10-24

阿里云服务器找不到了怎么解决方法

检查文件路径是否正确:确保你正在访问的文件路径是正确的。如果你不确定文件的路径,请使用绝对路径或相对路径来访问它。检查文件是否被删除或移动过:如果你删除或移动了文件,可能会导致阿里云服务器上的文件列表丢失。如果你想要查找已经被删除或移动的文件,请使用数据恢复工具来尝试恢复它们。检查文件是否在阿里云上被更改过:如果你发现
阿里云服务器找不到了怎么解决方法
2023-10-28

新手怎么找到合适的Python第三方库

这篇文章主要介绍“新手怎么找到合适的Python第三方库”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“新手怎么找到合适的Python第三方库”文章能帮助大家解决问题。1、百度谷歌搜索明确自己的需求,
2023-07-06

shdoclc.dll是什么以及提示找不到的解决方法

本篇文章给大家分享的是有关shdoclc.dll是什么以及提示找不到的解决方法,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。今天介绍一个新的dll文件,shdoclc.dll文
2023-06-14

大学生如何备考软考?我花了两年才找到正确的学习方法!

  早在2020年步入大学之时,就在一次讲座中了解到了软考。在大一第二个学期末,买了一本软考初级程序员教程。看着那厚厚的教程,再看了看大纲,只觉得教程繁琐,实在是没办法坚持明天学,之后那本教程便放在了书架上。  一、报班学习软件设计师  直到2022年末,大三过去一半了,我想,不能再等了。  想着看完那么一本书实在难熬
大学生如何备考软考?我花了两年才找到正确的学习方法!
2024-04-19

怎么才能找到适合你的云计算方案

人类社会进入了信息时代,互联网的出现使我们人与人之间的距离更近了,无论天涯海角,只要有信号,人们都可以通过互联网来互相联系。云计算的出现使得互联网的应用也是更加广泛,功能也更加强大。但是现在的互联网已经不再是以前传统的互联网了。云计算是什么
2023-06-03

刚买的阿里云服务器找不到怎么办?解决方法在此

如果您刚购买了阿里云服务器,但是找不到它,这可能是由于一些常见的问题或设置问题。本文将为您提供解决这些问题的方法。阿里云服务器是一种虚拟服务器,可以为您提供弹性的计算资源和存储空间。如果您刚购买了阿里云服务器,但是找不到它,这可能是由于一些常见的问题或设置问题。以下是一些可能的原因和解决方法:阿里云服务器未启动或
刚买的阿里云服务器找不到怎么办?解决方法在此
2023-11-16

win8.1找不到媒体流选项怎么办?win8.1系统找不到媒体流选项的解决方法图文教程

在Win8.1操作系统中自带有免费的Windows Media Player播放器,但是一些细心的用户发现Windows Media Player播放器中找不到媒体流选项,找了很久还是没发现,怎么回事呢?针对此故障问题,下面教程和大家分享下
2022-06-04

Win8找不到cmd运行选项怎么办?Win8找不到cmd运行选项的解决办法

Win8找不到cmd运行选项怎么办?cmd的命令行是一个很实用的工具,win8系统下也是很常用。可是win8没有开始菜单栏,找不到运行框时怎么操作?下面小编就给大家带来Win8找不到cmd运行选项的解决办法,一起来看看吧! 方法步骤 1、使
2022-06-04

win10找不到扬声器输出设备该怎么办win10找不到扬声器输出设备解决方法

扬声器输出设备一般是指音箱等设施,客户应用win10收看各种各样电视剧的情况下假如外向便会使用扬声器,可是有些客户应用的情况下提示信息找不到扬声器输出设备,那样碰到win10找不到扬声器输出设备怎么办呢,接下来就告诉大家相关win10找不到
2023-07-14

eclipse无法找到要运行的ant文件怎么解决

如果Eclipse无法找到要运行的Ant文件,你可以尝试以下方法来解决问题:确保Ant插件已经正确安装在Eclipse中。你可以在Eclipse的Marketplace中搜索Ant插件并安装。确保Ant文件路径正确。打开Eclipse中的A
eclipse无法找到要运行的ant文件怎么解决
2024-03-01

win8.1系统打开QQ提示QQ.exe无法找到入口怎么办?解决方法

腾讯QQ成为使用最广泛的聊天工具,有些用户在Win8.1系统下打开QQ以及一些其他程序的时候,常常会出现“QQ.exe无法找到入口”提示,导致程序无法安装运行。为什么会发生这样的情况呢?这通常是由于Win8.1中的某
2022-06-04

怎么在idea中查找类的某个方法

怎么在idea中查找类的某个方法?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1、使用 ctrl+F12打开类中所有方法的界面2、然后直接键盘中输入方法名称或者方法包含的字母,
2023-06-06

Python怎么在字符串中找到正则表达式所匹配的所有子串

这篇“Python怎么在字符串中找到正则表达式所匹配的所有子串”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python怎么
2023-06-08

php7找不到sql server驱动的原因和解决方法是什么

这篇“php7找不到sql server驱动的原因和解决方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“php7找不
2023-07-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录