gpt4 book ai didi

api - Java标准库: Which methods are with biggest number of arguments in the library?

转载 作者:行者123 更新时间:2023-12-01 07:17:16 25 4
gpt4 key购买 nike

Java 标准库中哪些方法的参数数量最多?

注意:变量参数 (Varargs) 应计为数组类型的 1 个参数,而不是无限数量的参数。

原因:我正在尝试设计更好的库,并且我正在考虑禁止使用超过 4 个参数的方法...
所以我试图在标准库中找到具有大量参数的方法并研究该方法并考虑是否需要这样定义它以及是否存在具有超过 4 个参数的有效案例。

最佳答案

限制自己的公共(public) API 中的参数数量当然是一个很好的目标,但不应盲目地遵守任意规则,然后应用古怪的变通方法来遵循它们。另外,other people's code有时应该只是如何不解决问题的灵感......

也就是说,回答实际问题有点困难。你想要_____吗...

  • 只关注 publicprotected方法?
  • 只考虑 public上课?
  • 在 JavaFX 之类的类中包含方法?
  • 在类中包含 public 的方法,但专有API?
  • ...


  • 不过,我很好奇。使用 class to scan for all visible classes (那里+1!),加载它们(并公然忽略错误),从有效类中获取所有方法并查看它们的参数计数,我可以找到一些结果:
  • 总冠军似乎来自 JavaFX 运行时的一个类,称为 com.sun.scenario.effect.impl.sw.sse.SSEPhongLighting_SPOTPeer。 .方法是native简称为 filter 的方法,并收到高达 37个参数 : private static native void com.sun.scenario.effect.impl.sw.sse.SSEPhongLighting_SPOTPeer.filter(int[],int,int,int,int,int,int[],float,float,float,float,int,int,int,float,float[],float,float,float,float,float,float,float,float,float,float,int[],float,float,float,float,int,int,int,float,float,float) .

    但是,方法是privatenative ,并且在 OpenJDK JavaFX 运行时存储库中甚至找不到该类,因此我假设它是自动生成的。
  • 将整个搜索限制为 public也是 public 的类和方法或 protected (而不是 native )仍然导致 JavaFX 类之一。这一次,它在 com.sun.prism.impl.VertexBuffer类,它有一个名为 addMappedPgram 的方法, 与 24个参数 : public final void com.sun.prism.impl.VertexBuffer.addMappedPgram(float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float,float) ,并且 repo 还包含 the source code of this method .

    这是大多数编码指南会说参数数量太多的方法示例。但是参数是如此“常规”(遵循命名模式,可能与四边形的 4 个角有关),我认为这样的事情仍然是合理的。但是该类仍然不应该被客户端使用,并且必须被视为“专有API”。
  • 省略以 "sun." 开头的包中的类或 "com.sun."给我们带来了可能被认为是问题的“正确答案”:类org.w3c.dom.events.MouseEvent包含一个名为 initMouseEvent 的方法, 它仍然接收 15个参数 : public abstract void org.w3c.dom.events.MouseEvent.initMouseEvent(java.lang.String,boolean,boolean,org.w3c.dom.views.AbstractView,int,int,int,int,int,boolean,boolean,boolean,boolean,short,org.w3c.dom.events.EventTarget) .这里是 the JavaDoc API documentation of that method .

  • (相关的附注:到目前为止,我遇到的客户端应该使用的参数数量最多的函数是 function from cuDNN 31 个参数 ...)

    更新

    作为对评论的回应,我现在还介绍了构造函数。

    类(class) javafx.scene.input.ScrollEvent有两个带有 的构造函数23个参数 ,即 public javafx.scene.input.ScrollEvent(javafx.event.EventType,double,double,double,double,boolean,boolean,boolean,boolean,boolean,boolean,double,double,double,double,double,double,javafx.scene.input.ScrollEvent$HorizontalTextScrollUnits,double,javafx.scene.input.ScrollEvent$VerticalTextScrollUnits,double,int,javafx.scene.input.PickResult)public javafx.scene.input.ScrollEvent(java.lang.Object,javafx.event.EventTarget,javafx.event.EventType,double,double,double,double,boolean,boolean,boolean,boolean,boolean,boolean,double,double,double,double,javafx.scene.input.ScrollEvent$HorizontalTextScrollUnits,double,javafx.scene.input.ScrollEvent$VerticalTextScrollUnits,double,int,javafx.scene.input.PickResult) .这里是 link to the API documentation对于后者。

    我用于测试的代码 - 这很难看而且很hacky,但我认为应该在此处添加:

    (编辑也涵盖了构造函数,以回应评论:)
    import java.io.File;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Executable;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.Enumeration;
    import java.util.List;
    import java.util.function.Predicate;
    import java.util.jar.JarEntry;
    import java.util.jar.JarFile;

    public class ArgCounting
    {
    static class Entry
    {
    Class<?> clazz;
    Executable executable;
    int numParams;
    }

    public static void main(String[] args) throws Exception
    {
    List<Entry> entries = new ArrayList<Entry>();
    ClassFinder.findClasses(new Visitor<String>()
    {
    @Override
    public boolean visit(String clazz)
    {
    try
    {
    System.out.println(clazz);
    Class<?> c = Class.forName(clazz);
    Method[] methods = c.getDeclaredMethods();
    for (Method method : methods)
    {
    Entry entry = new Entry();
    entry.clazz = c;
    entry.executable = method;
    entry.numParams = method.getParameterCount();
    entries.add(entry);
    }
    Constructor<?>[] constructors = c.getDeclaredConstructors();
    for (Constructor<?> constructor : constructors)
    {
    Entry entry = new Entry();
    entry.clazz = c;
    entry.executable = constructor;
    entry.numParams = constructor.getParameterCount();
    entries.add(entry);
    }
    }
    catch (Throwable e)
    {
    System.out.println("Ignoring: " + e);
    }
    return true;
    }
    });

    System.out.println("There are " + entries.size() + " executables");

    Predicate<Entry> executableIsNotNative =
    e -> !Modifier.isNative(e.executable.getModifiers());
    Predicate<Entry> executableIsPublic =
    e -> Modifier.isPublic(e.executable.getModifiers());
    Predicate<Entry> executableIsProtected =
    e -> Modifier.isProtected(e.executable.getModifiers());
    Predicate<Entry> classIsPublic =
    e -> Modifier.isPublic(e.clazz.getModifiers());

    List<String> skippedPackagePrefixes = Arrays.asList(
    "sun.", "com.sun.");
    Predicate<Entry> isSkipped = e ->
    {
    for (String prefix : skippedPackagePrefixes)
    {
    Package p = e.clazz.getPackage();
    if (p != null)
    {
    if (p.getName().startsWith(prefix))
    {
    return true;
    }
    }
    }
    return false;
    };
    Predicate<Entry> isNotSkipped = isSkipped.negate();

    Predicate<Entry> executableIsRelevant =
    executableIsNotNative.and(executableIsPublic.or(executableIsProtected));

    System.out.println("Methods:");
    printAllMax(entries,
    classIsPublic.and(executableIsRelevant).and(isNotSkipped).and(e -> e.executable instanceof Method));

    System.out.println("Constructors:");
    printAllMax(entries,
    classIsPublic.and(executableIsRelevant).and(isNotSkipped).and(e -> e.executable instanceof Constructor));
    }

    private static void printAllMax(Collection<Entry> entries, Predicate<Entry> filter)
    {
    int max = entries.stream()
    .filter(filter)
    .mapToInt(e -> e.numParams)
    .max()
    .getAsInt();

    System.out.println("Having " + max + " parameters:");
    entries.stream().filter(filter.and(e -> e.numParams == max)).forEach(e ->
    {
    System.out.println(e.executable);
    });
    }

    }

    // From https://stackoverflow.com/a/19554704/3182664
    interface Visitor<T>
    {
    /**
    * @return {@code true} if the algorithm should visit more results,
    * {@code false} if it should terminate now.
    */
    public boolean visit(T t);
    }

    // From https://stackoverflow.com/a/19554704/3182664
    class ClassFinder
    {
    public static void findClasses(Visitor<String> visitor)
    {
    String classpath = System.getProperty("java.class.path");
    String[] paths = classpath.split(System.getProperty("path.separator"));

    String javaHome = System.getProperty("java.home");
    File file = new File(javaHome + File.separator + "lib");
    if (file.exists())
    {
    findClasses(file, file, true, visitor);
    }

    for (String path : paths)
    {
    file = new File(path);
    if (file.exists())
    {
    findClasses(file, file, false, visitor);
    }
    }
    }

    private static boolean findClasses(File root, File file,
    boolean includeJars, Visitor<String> visitor)
    {
    if (file.isDirectory())
    {
    for (File child : file.listFiles())
    {
    if (!findClasses(root, child, includeJars, visitor))
    {
    return false;
    }
    }
    }
    else
    {
    if (file.getName().toLowerCase().endsWith(".jar") && includeJars)
    {
    JarFile jar = null;
    try
    {
    jar = new JarFile(file);
    }
    catch (Exception ex)
    {

    }
    if (jar != null)
    {
    Enumeration<JarEntry> entries = jar.entries();
    while (entries.hasMoreElements())
    {
    JarEntry entry = entries.nextElement();
    String name = entry.getName();
    int extIndex = name.lastIndexOf(".class");
    if (extIndex > 0)
    {
    if (!visitor.visit(
    name.substring(0, extIndex).replace("/", ".")))
    {
    return false;
    }
    }
    }
    }
    }
    else if (file.getName().toLowerCase().endsWith(".class"))
    {
    if (!visitor.visit(createClassName(root, file)))
    {
    return false;
    }
    }
    }

    return true;
    }

    private static String createClassName(File root, File file)
    {
    StringBuffer sb = new StringBuffer();
    String fileName = file.getName();
    sb.append(fileName.substring(0, fileName.lastIndexOf(".class")));
    file = file.getParentFile();
    while (file != null && !file.equals(root))
    {
    sb.insert(0, '.').insert(0, file.getName());
    file = file.getParentFile();
    }
    return sb.toString();
    }
    }

    (注意: ClassFinder 来自 https://stackoverflow.com/a/19554704/3182664!)

    关于api - Java标准库: Which methods are with biggest number of arguments in the library?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57137452/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com