【问题标题】:Is there any way to use an interface non staticly有什么方法可以非静态使用接口
【发布时间】:2020-06-23 16:39:11
【问题描述】:

我正在尝试将扩展集合实现为接口以及不断向我发送"Non-static method 'of(java.util.Collection<ELEMENT_TYPE>)'" cannot be referenced from a static context" 的方法

我知道它已在其他线程上得到回答,但所有这些答案都不能解决我的问题。

提前致谢。

编译器告诉我

**

Error:(22, 54) java: non-static method <ELEMENT_TYPE>of(java.util.Collection<ELEMENT_TYPE>) cannot be referenced from a static context

Error:(31, 62) java: non-static method <ELEMENT_TYPE>of(java.util.Collection<ELEMENT_TYPE>) cannot be referenced from a static context

Error:(22, 63) java: cannot find symbol
  symbol:   method map(this::mapper)
  location: interface java.util.Collection

Error:(31, 71) java: cannot find symbol
  symbol:   method toMap((it)->it.s[...]0, 2))
  location: interface java.util.Collection

Error:(40, 64) java: cannot find symbol
  symbol:   method toSet()
  location: interface java.util.Collection

Error:(40, 55) java: non-static method <ELEMENT_TYPE>of(java.util.Collection<ELEMENT_TYPE>) cannot be referenced from a static context
**

我确定我无权编辑测试文件

编辑:

我将 switch 重写为:

static <ELEMENT_TYPE> ExtendedCollection<ELEMENT_TYPE> of(Collection<ELEMENT_TYPE> list)
    {
        ExtendedCollection<ELEMENT_TYPE> c = new Collection<ELEMENT_TYPE>();
        list.forEach(e -> c.add(e));
        return (ExtendedCollection<ELEMENT_TYPE>) c;
    }

它现在几乎可以工作了我不知道如何实例化扩展集合,因为它是一个接口

【问题讨论】:

  • 请标记收到错误消息的确切行。
  • 我添加了他们感谢您的快速回答
  • 我们仍然不知道您的源文件中的第 22 行或第 31 行是什么。请在上面列出的源文件中标记出现错误的行。就像实际上放一个注释表明这是有错误的行。
  • 您应该在问题中包含ExtendedCollection 的定义。此外,请在问题中指定确切的要求,而不是期望读者向下滚动并从附加到不同答案的 cmets 中收集位和字节。

标签: java generics collections interface extends


【解决方案1】:
  1. 您将of 声明为非静态方法,但尝试静态访问它。
    • 解决方案 a:在实例上调用 of
    • 解决方案 b(首选):声明 of static(只需将 default &lt;ELEMENT_TYPE&gt; Collection&lt;ELEMENT_TYPE&gt; of... 替换为 static &lt;ELEMENT_TYPE&gt; Collection&lt;ELEMENT_TYPE&gt; of...
  2. 见 1.
  3. toMap 没有为Collection 定义,可能是最好的解决方案:使of 返回ExtendedCollection(而不是“正常”Collection;)
  4. 和 5. 与 3. - 6. 由 1. 相关/将被修复。

是的,将返回类型更改为ExtendedCollection 并不是“那么简单”:这里至少您必须初始化/提供一个实现,如果您不选择一个已经提供的基类,是的add,你必须实现它:

static <ELEMENT_TYPE> ExtendedCollection<ELEMENT_TYPE> of(Collection<ELEMENT_TYPE> list)
{
   ExtendedCollection<ELEMENT_TYPE> c = new MyExtendedCollectionImpl<>();
   list.forEach(e -> c.add(e));
   return c;
}

与:

class MyExtendedCollectionImpl<T>
  extends java.util.ArrayList<T> /* e.g. ...  https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html */
  implements ExtendedCollection<T> { 
     // implement/override ExtendedCollection methods, if any
     // done!
} 

【讨论】:

  • 用 ExtendedCollection 替换 Collection 似乎是关键,但由于我没有实现 add 方法,我该怎么做?
  • 几乎是这样,除了 new MyExtendedCollectionImpl();没有实现,因为它是一个接口。我必须重新实现 Collection 的每个元素吗?
  • nono,...Impl必须是一个类,没有接口..一个接口,有no的implementor(somewhere)可以认为没用...
【解决方案2】:

试图扩展集合是错误的做法。

您只能在实现该接口的事物上调用这些方法,这意味着您不能重用现有的、经过实战考验的集合实现,例如 java.util.ArrayList

只需定义静态辅助方法,并在需要时传入集合。

事实上,这就是你的“接口”实际在做的事情:你可以定义 of 方法,比如:

static  <ELEMENT_TYPE> Collection<ELEMENT_TYPE> of(Collection<ELEMENT_TYPE> list)
{
    Collection<ELEMENT_TYPE> c = new ArrayList<ELEMENT_TYPE>();
    list.forEach(e -> c.add(e));
    return c;
}

或者,更简单:

static  <ELEMENT_TYPE> Collection<ELEMENT_TYPE> of(Collection<ELEMENT_TYPE> list)
{
    return new ArrayList<>(list);
}

或者直接内联该代码。您实际得到的内容更清晰,它是标准的,而且更灵活(不过,您可以通过将参数类型更改为 Collection&lt;? extends ELEMENT_TYPE&gt; 来获得同样的灵活性)。

【讨论】:

  • 如果我这样做,我会遇到下面描述的其他问题
  • @Archozy 如果你做了what,你指的是“下面”的哪一点?
  • @AndyTurner 然后你必须创建一个implements 接口的类并实例化该类以创建可以调用方法的对象。
  • @Code-Apprentice 如果使用静态方法,则不需要创建这样的类。
  • 我会在static 上下文中使用与ELEMENT_TYPE 不同的名称以避免潜在的混淆。但也许我是唯一可能对此感到困惑的人。
【解决方案3】:

改变方法:

static <ELEMENT_TYPE> Collection<ELEMENT_TYPE> of(Collection<ELEMENT_TYPE> list)
    {
        Collection<ELEMENT_TYPE> c = new ArrayList<ELEMENT_TYPE>();
        list.forEach(e -> c.add(e));
        return c;
    }

错误切换到: ** 错误:(22, 63) java: 找不到符号 符号:方法映射(this::mapper) 位置:接口java.util.Collection

错误:(31, 71) java: 找不到符号 符号:方法 toMap((it)->it.s[...]0, 2)) 位置:接口java.util.Collection

错误:(40, 64) java: 找不到符号 符号:方法 toSet() 位置:接口java.util.Collection

错误:(46, 64) java: 找不到符号 符号:方法 toList() 位置:接口 java.util.Collection **

【讨论】:

    【解决方案4】:

    这里的问题是您试图在静态上下文中使用非静态方法。您的方法ExtendedCollection#of() 未标记为静态,但您正在尝试静态使用它。这意味着,您需要先创建ExtendedCollection 的实例,而不是调用ExtendedCollection.of(list)。 (ExtendedCollection collection = new ExtendedCollection();.

    但是,由于它是一个接口,您需要实例化一个子类。 (虽然,我不明白为什么你不能让ExtendedCollection 成为一个类而不是一个接口。它似乎只添加了默认方法而不是任何没有实现的方法。另外,正如安迪·特纳建议的那样,你可能想要这样做类是一个静态帮助程序/实用程序类,您可以在其中传递集合,然后对其进行转换。

    【讨论】:

    • 我会改变一个类的界面,但这是练习
    • 啊。演习的具体要求是什么?因为最好只将方法定义为抽象,而在接口中,然后用实现创建一个单独的类。此外,您能够制作静态接口方法(正如所有其他人所指出的那样),但这似乎不是您想要做的。您最好的选择是实例化一个子类,然后使用它来调用方法。
    【解决方案5】:

    错误消息表示您在静态上下文中使用非静态方法of()。静态上下文是当您使用ClassName.methodName() 时。有两种方法可以解决这个问题:

    1. 创建一个具有您要调用的方法的实例。由于在接口中声明了方法,所以需要先创建一个实现该接口的类:

      public class ExtendedList<T> implements ExtendedCollection<T> {
      }
      

      现在你可以创建一个实例了:

      ExtendedCollection<String> c = new ExtendedCollection<>();
      final List<Integer> ints = c.of(list).map(this::mapper);
      
    2. 将您的 interface 更改为 class 并将该方法声明为静态:

      static <ELEMENT_TYPE> Collection<ELEMENT_TYPE> of(Collection<ELEMENT_TYPE> list) {
          Collection<ELEMENT_TYPE> c = new ArrayList<ELEMENT_TYPE>();
          list.forEach(e -> c.add(e));
          return c;
      }
      

    对于您在此处尝试完成的任务,将方法声明为静态可能最有意义。

    【讨论】:

    • 我想这样做,但我没有权利我必须保留1个接口和所有方法的原型(除了)
    • @AndyTurner 然后你必须创建一个implements 接口的类并实例化该类以创建可以调用方法的对象。
    【解决方案6】:

    您正在从static 上下文(即,不调用它ExtendedCollection实例)。

    如果您使用的是 java 8 或更高版本,您可以interfaces 上定义 static 方法。在这种情况下,您需要做的就是通过删除default 修饰符并添加static 来更改of 方法声明。

    如果你使用 pre java 8,那么这就是为什么 java 有 CollectionsExecutors 等类的原因。你可以定义一个 utility 类它具有 static 方法来返回 interface 类型的项目。

    【讨论】:

    • Pre java 8 不太可能,因为接口中的默认方法是在 java 8 中引入的;)
    • @Manziel:是的,显然在观看时完全忽略了这一点。仍然保留该部分,以便为面临类似问题的任何人提供更通用的答案。
    猜你喜欢
    • 2020-12-31
    • 2015-11-13
    • 1970-01-01
    • 1970-01-01
    • 2019-10-06
    • 2011-04-23
    • 2014-08-06
    • 2015-03-14
    • 1970-01-01
    相关资源
    最近更新 更多