当前位置: 首页 > 面试题库 >

如何扩展Java以引入引用传递?

酆勇
2023-03-14
问题内容

Java是按价值传递的。您如何修改语言以引入引用传递(或某些等效行为)?

以类似的东西为例

public static void main(String[] args) {
    String variable = "'previous String reference'";
    passByReference(ref variable);
    System.out.println(variable); // I want this to print 'new String reference'
}

public static void passByReference(ref String someString) {
    someString = "'new String reference'";
}

哪个(不带ref)编译为以下字节

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String 'previous String reference'
       2: astore_1
       3: aload_1
       4: invokestatic  #3                  // Method passByReference:(Ljava/lang/String;)V
       7: return

  public static void passByReference(java.lang.String);
    Code:
       0: ldc           #4                  // String 'new String reference'
       2: astore_0
       3: return

的代码3:将参考从变量加载到堆栈上variable

我正在考虑的一种可能性是让编译器确定一个方法可以通过引用传递ref,并可能通过来更改该方法以接受一个Holder对象,该对象存储与我们的变量相同的引用。该方法完成后,并可能更改了持有人的引用,则调用方方值的变量将替换为持有人的引用值。

它应该编译为此

public static void main(String[] args) {
    String variable = "'previous String reference'";
    Holder holder = Holder.referenceOf(variable);
    passByReference2(holder);
    variable = (String) holder.getReference(); // I don't think this cast is necessary in bytecode
    System.out.println(variable);
}

public static void passByReference(Holder someString) {
    someString.setReference("'new String reference'");
}

这里Holder可能是这样的

public class Holder {
    Object reference;
    private Holder (Object reference) {
        this.reference = reference;
    }
    public Object getReference() {
        return this.reference;
    }
    public void setReference(Object reference) {
        this.reference = reference;
    }
    public static Holder referenceOf(Object reference) {
        return new Holder(reference);
    }
}

这在哪里会失败,或者您如何改进呢?


问题答案:

要回答您的问题:

这在哪里失败?

  1. 最终变量和枚举常量
  2. “特殊”参考,例如 this
  3. 从方法调用返回的引用,或使用内联构造的引用 new
  4. 文字(字符串,整数等)

…还有可能是其他人。基本上,ref仅当参数源是非最终字段或局部变量时,您的关键字才可用。与一起使用时,任何其他来源都应产生编译错误ref

(1)的示例:

final String s = "final";
passByReference(ref s);  // Should not be possible

(2)的示例:

passByReference(ref this);  // Definitely impossible

(3)的示例:

passByReference(ref toString());  // Definitely impossible
passByReference(ref new String("foo"));  // Definitely impossible

(4)的示例:

passByReference(ref "literal");  // Definitely impossible

然后是赋值表达式,在我看来,这就像一个判断调用:

String s;
passByReference(ref (s="initial"));  // Possible, but does it make sense?

您的语法ref在方法定义和方法调用中都需要关键字也有点奇怪。我认为方法定义就足够了。



 类似资料:
  • 扩展说明 当有服务引用时,触发该事件。 扩展接口 org.apache.dubbo.rpc.InvokerListener 扩展配置 <!-- 引用服务监听 --> <dubbo:reference listener="xxx,yyy" /> <!-- 引用服务缺省监听器 --> <dubbo:consumer listener="xxx,yyy" /> 已知扩展 org.apache.dub

  • 我正在做一个项目,该项目将有许多JavaFX应用程序,这些应用程序具有相似但又足够不同的功能,因此我创建了一个抽象基类来扩展Application以处理常见的功能并指示它们需要做什么,还创建了一系列具体的类来扩展这些功能。然而,当我试图跑的时候,我得到 应用程序构造函数java.lang.Reflect.InvocationTargetException位于java.base/jdk.intern

  • 本文向大家介绍如何引入scss?引入后如何使用?相关面试题,主要包含被问及如何引入scss?引入后如何使用?时的应答技巧和注意事项,需要的朋友参考一下 安装scss依赖包: 在build文件夹下修改 webpack.base.conf.js 文件: 在 module 下的 rules 里添加配置,如下: 应用: 在vue文件中应用scss时,需要在style样式标签上添加lang="scss",即

  • 问题内容: 您可以使用关键字“ ref”在.NET中进行操作。用Java有什么办法吗? 问题答案: 您正在用自己的方法做什么?如果仅填充现有数组,则不需要.NET或Java中的按引用传递语义。在这两种情况下,引用都将按值传递-因此对 对象的 更改将由调用者看到。这就像告诉某人您的住所地址,并要求他们向其提供物品-没问题。 如果您 确实 需要传递引用语义,即调用方将看到对参数本身所做的任何更改,例如

  • 我正在使用Gradle构建一个jar,其中包含META-INF中的xml文件。此文件的行如下 允许针对不同环境使用不同的SQL数据库。我想告诉gradle从项目属性展开${SQLDialent}。 我试过这个: 但是它因为而失败,在我看来,Jar任务也试图扩展文件中的属性。所以我尝试了 这不会引发上述异常,而是导致所有资源被复制两次—一次使用属性扩展,一次不使用属性扩展。我设法解决了这个问题 这正

  • 问题内容: 在C ++中,如果需要修改2个对象,则可以按引用传递。您如何在Java中完成此操作?假设这两个对象是基本类型,例如int。 问题答案: 你不能 Java不支持传递对变量的引用。一切都通过价值传递。 当然,当通过值传递对对象的引用时,它将指向同一对象,但这 不是通过reference调用 。