计算 Java 函数的签名

发布于 2024-12-14 15:03:25 字数 180 浏览 3 评论 0原文

有没有办法计算 Java 类的方法签名?签名
就像 ([Ljava/lang/String;)V 表示一个以 String[] 作为参数的函数
并返回void

计算签名的规则是什么?

Is there a way to compute a Java class's method's signature? A signature
like ([Ljava/lang/String;)V represents a function that takes a String[] as argument
and returns void.

What's the rule to compute the signature?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

带上头具痛哭 2024-12-21 15:03:25

它始终是一组括号,包围着参数的类型指示符,一个接一个,没有逗号或任何其他内容,紧接着是右括号后面的返回值的类型指示符。这非常简单。

这是一个类型签名表:

Signature    Java Type
Z    boolean
B    byte
C    char
S    short
I    int
J    long
F    float
D    double
V    void
L fully-qualified-class ;    fully-qualified-class
[ type   type[]

最后两个意味着要命名一个类,例如,Ljava/lang/Object;,并命名一个数组(例如)int,你说[I,而int的数组的数组就是[[I

如果您想根据反射来计算 Java 代码中的签名,那就很简单了;只需使用上面的表格以及处理对象和数组的规则即可。

It's always a set of parentheses enclosing type signifiers for the arguments, one after the other with no commas or anything, followed by a type signifier for the return value after the closing paren. It's pretty straightforward.

Here’s a table of type signatures:

Signature    Java Type
Z    boolean
B    byte
C    char
S    short
I    int
J    long
F    float
D    double
V    void
L fully-qualified-class ;    fully-qualified-class
[ type   type[]

Those last two mean that to name a class, you say, for example, Ljava/lang/Object;, and to name an array of (for example) int, you say [I, and an array of array of int is [[I.

If you wanted to literally compute the signature in Java code based on reflection, it'd be simple enough; just use the table above with rules for handling objects and arrays.

遇到 2024-12-21 15:03:25

只需在包含 .class 文件的文件夹中运行 javap -s 即可。它会100%准确地告诉你。这些事情无需猜测。

Just run javap -s <class-name> in the folder containing the .class files . It will tell you with 100% accuracy. No need to guess these things.

傲世九天 2024-12-21 15:03:25

快速谷歌搜索发现了这个网页:

http://www.rgagnon.com/javadetails/ java-0286.html

签名有两部分。第一部分括在括号内,表示方法的参数。第二部分位于右括号之后,表示返回类型。 Java类型和C类型之间的映射是

类型字符 
布尔值 Z 
字节B 
字符C 
双D 
浮动F 
整数我 
长J 
对象L 
短裤 
无效V 
大批 [ 

A quick google search uncovered this webpage:

http://www.rgagnon.com/javadetails/java-0286.html

There are two parts to the signature. The first part is enclosed within the parentheses and represents the method's arguments. The second portion follows the closing parenthesis and represents the return type. The mapping between the Java type and C type is

Type     Chararacter 
boolean      Z 
byte         B 
char         C 
double       D 
float        F 
int          I 
long         J 
object       L 
short        S 
void         V 
array        [ 
会发光的星星闪亮亮i 2024-12-21 15:03:25

请参阅此处了解一些详细信息。

基本上是参数,然后返回值。

See here for some details.

Basically it's params, then return value.

奶茶白久 2024-12-21 15:03:25

来自 JLS,§8.4.2

8.4.2 方法签名

方法的签名由方法的名称和方法组成
方法的形式参数的数量和类型。一个类可以不
声明两个具有相同签名的方法,否则会出现编译时错误
发生。

示例:

类 Point 实现 Move {
  整数x,y;
  抽象无效移动(int dx,int dy);
  void move(int dx, int dy) { x += dx; y+=dy; }
}

导致编译时错误,因为它声明了两个 move 方法
具有相同的签名。这是一个错误,即使其中之一
声明是抽象

所以“规则”是

方法的名称以及方法的形式参数的数量和类型

From the JLS, §8.4.2:

8.4.2 Method Signature

The signature of a method consists of the name of the method and the
number and types of formal parameters to the method. A class may not
declare two methods with the same signature, or a compile-time error
occurs.

The example:

class Point implements Move {
  int x, y;
  abstract void move(int dx, int dy);
  void move(int dx, int dy) { x += dx; y += dy; }
}

causes a compile-time error because it declares two move methods
with the same signature. This is an error even though one of the
declarations is abstract.

So the "rule" is

the name of the method and the number and types of formal parameters to the method

清欢 2024-12-21 15:03:25

You can find this information in the the Java Virtual Machine Specification

攒一口袋星星 2024-12-21 15:03:25

有没有办法计算 Java 类的方法签名?

您可以使用 apache commons-bcel

package com.mageddo.coc.classes;

import java.io.IOException;

import com.sun.org.apache.bcel.internal.classfile.ClassParser;

public class JavaClass {

  public static String structureAsText(Class<?> clazz) throws IOException {

    final String classPath =
        String.format(
            "/%s.class",
            clazz.getName()
                .replace('.', '/')
        );

    final ClassParser classParser = new ClassParser(
        JavaClass.class.getResourceAsStream(classPath),
        clazz.getSimpleName() + ".java"
    );

    
    return classParser.parse()
        .toString();
  }

  public static void main(String[] args) throws IOException {
    System.out.println(JavaClass.structureAsText(JavaClass.class));
  }

}

输出以编程方式完成此操作

public class com.mageddo.coc.classes.JavaClass extends java.lang.Object
filename        JavaClass.java
compiled from       JavaClass.java
compiler version    52.0
access flags        33
constant pool       98 entries
ACC_SUPER flag      true

Attribute(s):
    SourceFile: JavaClass.java

3 methods:
    public void <init>()
    public static String structureAsText(Class clazz) [Signature: (Ljava/lang/Class<*>;)Ljava/lang/String;]
        throws Exceptions: java.io.IOException
    public static void main(String[] args)
        throws Exceptions: java.io.IOException

Is there a way to compute a Java class's method's signature?

You can do it programmatically by using apache commons-bcel

package com.mageddo.coc.classes;

import java.io.IOException;

import com.sun.org.apache.bcel.internal.classfile.ClassParser;

public class JavaClass {

  public static String structureAsText(Class<?> clazz) throws IOException {

    final String classPath =
        String.format(
            "/%s.class",
            clazz.getName()
                .replace('.', '/')
        );

    final ClassParser classParser = new ClassParser(
        JavaClass.class.getResourceAsStream(classPath),
        clazz.getSimpleName() + ".java"
    );

    
    return classParser.parse()
        .toString();
  }

  public static void main(String[] args) throws IOException {
    System.out.println(JavaClass.structureAsText(JavaClass.class));
  }

}

outputs

public class com.mageddo.coc.classes.JavaClass extends java.lang.Object
filename        JavaClass.java
compiled from       JavaClass.java
compiler version    52.0
access flags        33
constant pool       98 entries
ACC_SUPER flag      true

Attribute(s):
    SourceFile: JavaClass.java

3 methods:
    public void <init>()
    public static String structureAsText(Class clazz) [Signature: (Ljava/lang/Class<*>;)Ljava/lang/String;]
        throws Exceptions: java.io.IOException
    public static void main(String[] args)
        throws Exceptions: java.io.IOException
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文