Java Integer类中方法的值

Java Integer类中方法的值,java,Java,我们知道Integer类中方法的valueof是静态的。但当我们调用Integer类的对象时,它不会给出任何错误。下面的代码运行得很好 public class Test { public static void main(String[] args) { Integer i=new Integer(5); System.out.println(i.valueOf(i)); } } 更有趣的是这个案例: public class A {

我们知道Integer类中方法的valueof是静态的。但当我们调用Integer类的对象时,它不会给出任何错误。下面的代码运行得很好

public class Test {
    public static void main(String[] args)
    {

        Integer i=new Integer(5);
        System.out.println(i.valueOf(i));
    }
}

更有趣的是这个案例:

public class A {
  public static int foo() {
    return 0;
  }
}

public class B extends A{
  public static int foo() {
    return 1;
  }
}

public static void bar() {
  A a = new B();
  System.out.println("val: " + a.foo());
}

打印“0”,因为
a
被声明为
a

更有趣的是这种情况:

public class A {
  public static int foo() {
    return 0;
  }
}

public class B extends A{
  public static int foo() {
    return 1;
  }
}

public static void bar() {
  A a = new B();
  System.out.println("val: " + a.foo());
}

打印“0”,因为
a
声明为
a

引用Java教程中关于以下内容的内容:

注意:您还可以引用带有对象引用的静态方法,如
instanceName.methodName(args)
但这是不鼓励的,因为它没有明确说明它们是类方法

这应该是一个很好的官方来源


JLS似乎适用于:

  • 调用模式,计算如下:
    • 如果编译时声明具有
      static
      修饰符,则调用模式为
      static

  • 如果表单是ExpressionName。[TypeArguments]标识符,然后:
    • 如果调用模式是静态的,则没有目标引用。将计算ExpressionName,但随后将丢弃结果
  • 如果窗体是主窗体。[TypeArguments]涉及标识符,然后:
    • 如果调用模式是静态的,则没有目标引用。对主表达式求值,但随后丢弃结果
因此,只要定义了如何计算这类表达式的规则,就允许这样做。也就是说:

  • static
    方法总是使用
    static
    调用调用。(这似乎是显而易见的,但它仍然是应该指定的。比方说,假设Java在未来引入了类似C#扩展方法的东西,这些方法将遵循不同的规则。)
  • 出于静态方法调用的目的,将忽略receiver表达式的值。(尽管在调用之前会对其进行评估。)

这就是在运行时如何评估此类调用。这是一个不同于编译器如何确定要调用的方法的步骤,这一步骤发生在前面。然而,规范的这一部分对我来说是难以理解的。也就是说,很容易验证接收方表达式的编译时类型是否重要,调用的方法是
static
。(静态类型是编译器必须使用的所有类型,静态调用是早期绑定的。)

引用Java教程:

注意:您还可以引用带有对象引用的静态方法,如
instanceName.methodName(args)
但这是不鼓励的,因为它没有明确说明它们是类方法

这应该是一个很好的官方来源


JLS似乎适用于:

  • 调用模式,计算如下:
    • 如果编译时声明具有
      static
      修饰符,则调用模式为
      static

  • 如果表单是ExpressionName。[TypeArguments]标识符,然后:
    • 如果调用模式是静态的,则没有目标引用。将计算ExpressionName,但随后将丢弃结果
  • 如果窗体是主窗体。[TypeArguments]涉及标识符,然后:
    • 如果调用模式是静态的,则没有目标引用。对主表达式求值,但随后丢弃结果
因此,只要定义了如何计算这类表达式的规则,就允许这样做。也就是说:

  • static
    方法总是使用
    static
    调用调用。(这似乎是显而易见的,但它仍然是应该指定的。比方说,假设Java在未来引入了类似C#扩展方法的东西,这些方法将遵循不同的规则。)
  • 出于静态方法调用的目的,将忽略receiver表达式的值。(尽管在调用之前会对其进行评估。)

这就是在运行时如何评估此类调用。这是一个不同于编译器如何确定要调用的方法的步骤,这一步骤发生在前面。然而,规范的这一部分对我来说是难以理解的。也就是说,很容易验证接收方表达式的编译时类型是否重要,调用的方法是
static
。(静态类型是编译器必须使用的所有类型,静态调用是早期绑定的。)

静态方法可以像类方法一样调用,这是有效的,因为。。。Java的设计者是这么说的。除了从JLS复制粘贴外,不确定要给出什么答案。因为静态方法只能由类访问,而不能由对象访问。此代码工作得非常好,并且与文档描述的工作方式一致。@biziclop我将每个“忽略”改为“警告”,除了“非外部化字符串”、“装箱和取消装箱转换”,有时“方法可能是静态的”。在签入之前,代码应该没有警告。静态方法可以像类方法一样调用。这是有效的,因为。。。Java的设计者是这么说的。除了从JLS复制粘贴外,不确定要给出什么答案。因为静态方法只能由类访问,而不能由对象访问。此代码工作得非常好,并且与文档描述的工作方式一致。@biziclop I将每个“忽略”改为“警告”