当前位置: 首页 > 知识库问答 >
问题:

Java对象访问相同的整体实现

阎嘉荣
2023-03-14

也许问题的标题写得不好,但我不明白我还能写些什么。

我想了解,为什么下面两个案例中的第一个能起作用,以及在总体实现相同的情况下,如何让第二个也能起作用。

从代码的角度来看,什么样的原则使第一个按原样工作,也就是说,扩大了可以使用的变量的范围,所以我可以了解更多。

我想访问onclick侦听器中的'obj'变量。

案例1

public void onBindViewHolder(MyAdapater.ViewHolder viewHolder, final int position) {

    MyObject obj= memberVariable.get(position);

    viewHolder.getButton().setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // use obj because I can access it
        }
    });
}

案例2

public void onBindViewHolder(MyAdapater.ViewHolder viewHolder, final int position) {

    MyObject obj= memberVariable.get(position);

    viewHolder.getButton().setOnClickListener(this::approveItem);
}

private void approveItem(View view) {
// can't access the obj object now.
}

我的onclicklistener只接受带有onClick方法的接口,该方法只接受一个参数。所以不能通过obj考试。

共有2个答案

慕容聪
2023-03-14

这里的区别只是变量作用域。您的匿名类(new View. OnClickListener(){...})在方法的主体中声明,它可以访问其局部变量(有一些条件,但这些条件在这里不相关)。

您永远无法从其他方法访问方法局部变量。这是不允许的(就像它没有意义一样)。

当您使用这样的方法引用时,实际上是在“借用”该方法的代码来提供接口的实现(在您的例子中是View.OnClickListener)。该方法无法从调用它的位置了解局部变量。如果你仔细想想,这个方法可以从一个不同的位置调用,在这个位置,封闭范围内没有这样的变量。所以编译器不允许这样做。

你的选择是:

要么使用lambda表达式(假设View. OnClickListener可以作为函数接口):

viewHolder.getButton().setOnClickListener(view -> {
        // use obj because I can access it
});

或者,如果代码2的原因是将逻辑外部化,则使该方法采用第二个参数:

private void approveItem(View view, MyObject obj) {
   // use obj
}

并在通话中传递

viewHolder.getButton().setOnClickListener(view -> this.approveItem(view, obj));
臧烨烁
2023-03-14

在案例2中,obj显然不在approvietem方法的范围内。在案例1中,编译器隐式地将外部作用域的变量提供给匿名内部类。如果不想使用匿名内部类,则需要显式地传递obj,这在方法引用中是不可能的:

public void onBindViewHolder(MyAdapater.ViewHolder viewHolder, int position) {
    MyObject obj = memberVariable.get(position);
    viewHolder.getButton().setOnClickListener(view -> this.approveItem(view, obj));
}

private void approveItem(View view, MyObject obj) {
    // ...
}
 类似资料:
  • 问题内容: 代码段-1 代码段-2 尽管第二个代码段在不引起任何竞争条件的情况下运行良好,但第一个代码段未能成功同步同一类的不同实例(RequestObject)之间对静态数据成员的访问。有人可以对此进行更多说明。我想了解为什么第一种方法不起作用。 问题答案: 您将不断创建新的对象,然后对其进行同步,这至少使考虑它变得非常混乱。这样就可以得到以下情况: 线程A保持当前值(假设为0) 线程B排队等待

  • 问题内容: 我有一个JNI方法来访问返回一个Integer对象的java方法。我不想返回原始的int类型,因为将修改此代码以处理通用对象。以下是我所拥有的。我无法获得所传递的Integer的值。C ++端的输出类似于 如何获取在C ++端传递的Integer对象的实际值? 请帮忙。 谢谢, -H GenericPeer.cpp GenericPeer.java 资料库 Test.java(主类)

  • 问题内容: 我已经搜索了很多,但找不到特定的解决方案。关于stackoverflow也有一些问题,但我无法找到满意的答案,所以我再次询问。 我在java中有一个如下类。 我知道如何在Java中使用线程。 现在我想同时执行这两个操作。为此,我创建了两个线程类,一个在运行中执行addString()逻辑,另一个在执行deleteString()逻辑中。我在每个线程的构造函数中传递mylist,但是在对

  • 问题内容: 每个HTTP请求是否在不同的线程中访问相同的servlet对象?还是创建一个新的线程和新的Servlet实例? 问题答案: 如果您的servlet未实现,则容器将使用相同的servlet实例。否则,不能保证击中相同的物体。如果认为必要,容器可以自由创建更多的servlet实例。但是请求来自不同的线程,不一定是新创建的(如Sanjay所述)。 根据Servlet 3.0规范: 对于未在分

  • 带有同伴对象的简单示例类 值测试可以通过访问,但如何从MyClass的实例访问?如果我有,那么我如何从sample访问测试?不正确....有没有办法? Java,C++,python等都有很简单的解决方案...(我将为每个有帮助的is提供代码示例),我认为kotlin会有一个比使用Java更好的解决方案。 对于在没有对象实例(如工厂)的情况下访问类属性,kotlin companion objec

  • 我目前正在使用最新版本的实体框架进行一个项目,我遇到了一个似乎无法解决的问题。 当涉及到更新现有对象时,我可以很容易地更新对象属性,直到涉及到引用另一个类的属性为止。 在下面的示例中,我有一个名为Foo的类,它存储各种属性,其中2个是其他类的实例 当我使用下面的Edit()方法时,我传入了我想要更新的对象,并且我可以设法使名称正确更新,但是我还没有找到一种方法来更改子对象的属性。例如,如果子对象的