1

I'm trying to implement extended collections as an interface and the method of keep sending me "Non-static method 'of(java.util.Collection<ELEMENT_TYPE>)'" cannot be referenced from a static context"

I know it has been answered on other threads but all those answers don't solve my problem.

thanks in advance.

The compiler tell me

**

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
**

I precise that i don't have the right to edit the test file

Edit:

I rewrite switch to:

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;
    }

and it almost works now I don't know how to instantiate an Extended collection as it is an interface

Archozy
  • 13
  • 4
  • Please mark the exact lines that are receiving the error message. – markspace Mar 11 '20 at 16:20
  • i added them thanks for fast answer – Archozy Mar 11 '20 at 16:23
  • We still don't know what line 22 is or line 31 is in your source file. Please mark the lines that get errors in your source file that you listed above. Like actually put a comment indicating that this is the line that has an error. – markspace Mar 11 '20 at 16:25
  • https://stackoverflow.com/q/47430424/438992 – Dave Newton Mar 11 '20 at 16:25
  • (But you're not declaring the methods as `static` so I'm not sure what you expected, even given the complexities referenced in the above link.) – Dave Newton Mar 11 '20 at 16:27
  • Which parts of this code did your instructor give you and which parts are you writing yourself? – Code-Apprentice Mar 11 '20 at 16:40
  • 1
    You should include the definition of `ExtendedCollection` into your question. Further, specify the exact requirements right in the question, instead of expecting the reader to scroll down and collect the bits and bytes from comments attached to different answers. – Holger Mar 12 '20 at 17:43

6 Answers6

2

Trying to extend collection is the wrong thing to do.

You'll only be able to invoke these methods on a thing that implements the interface, meaning you can't, say, reuse existing, battle-tested implementations of collection like java.util.ArrayList.

Just define static helper methods, and pass in the collection if needed.

In fact, this is what your "interface" is actually doing: you could define the of method like:

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;
}

Or, easier:

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

Or just inline that code directly. It's clearer what you're actually getting, it's standard, and it's more flexible (you can gain the same flexibility by changing the parameter type to Collection<? extends ELEMENT_TYPE> though).

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • if I do this I have other problem I described below – Archozy Mar 11 '20 at 16:34
  • @Archozy if you do *what*, and which particular bit of "below" are you referring to? – Andy Turner Mar 11 '20 at 16:36
  • @AndyTurner Then you must create a class that `implements` the interface and instantiate that class to create objects that you can call the methods on. – Code-Apprentice Mar 11 '20 at 16:37
  • @Code-Apprentice if you use static methods, you don't need to create such a class. – Andy Turner Mar 11 '20 at 16:39
  • I'd use a different name than `ELEMENT_TYPE` from a `static` context to avoid potential confusion. But maybe I'm the only person who might be confused by that. – BeUndead Mar 11 '20 at 16:39
  • @AndyTurner I meant that comment to be below my own answer. The OP replied to my answer that he is unable to change the method signature to static. This is starting to sound like a homework assignment from a Data Structures course where the OP needs to implement their own collection class from scratch. – Code-Apprentice Mar 11 '20 at 16:41
1

You're calling the non static method, of (which you define on your ExtendedCollection interface) from a static context (i.e., not calling it on an instance of ExtendedCollection).

If you're using java 8 or later, you can define static methods on interfaces. In which case all you need to do is change the of method declaration by removing the default modifier and adding static.

If you're using pre java 8, then this is why java has classes like Collections, Executors, etc. You can define a utility class which has static methods to return items of the interface types.

BeUndead
  • 3,463
  • 2
  • 17
  • 21
  • 1
    Pre java 8 is unlikely as default methods in interfaces were introduced in java 8 ;) – Manziel Mar 11 '20 at 16:29
  • @Manziel: Yep, apparently completely blanked that when viewing. Still keeping that part in to make it a more general answer for anyone facing a similar problem though. – BeUndead Mar 11 '20 at 18:52
0

The error message means that you are using the non-static method of() in a static context. A static context is when you use ClassName.methodName(). There are two ways to fix the problem:

  1. Create an instance that has the method you want to call. Since you declare the method in an interface, you need to create a class that implements the interface first:

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

    Now you can create an instance:

    ExtendedCollection<String> c = new ExtendedCollection<>();
    final List<Integer> ints = c.of(list).map(this::mapper);
    
  2. Change your interface to a class and declare the method as static:

    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;
    }
    

For what you are trying to accomplish here, declaring the methods as static probably makes the most sense.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • I'd like to do this but I don't have the right i must keep 1 interface and the prototype of all methods (except of) – Archozy Mar 11 '20 at 16:35
  • @AndyTurner Then you must create a class that `implements` the interface and instantiate that class to create objects that you can call the methods on. – Code-Apprentice Mar 11 '20 at 16:41
0

The problem here is you are trying to use a non static method in a static context. Your method ExtendedCollection#of() is not marked static, but you are trying to use it statically. This means that instead of calling ExtendedCollection.of(list), you need to create an instance of ExtendedCollection before you do so. (ExtendedCollection collection = new ExtendedCollection();.

But, since it is an interface, you will need to instantiate a subclass. (Though, I don't see why you can't make ExtendedCollection a class instead of an interface. It only seems to add default methods and not any without implementation. Also, as Andy Turner suggested, you might want to make this class a static helper/utility class instead, where you pass the collection, then transform it.

solonovamax
  • 138
  • 5
  • I'd change the interface for a class but this is the exercise – Archozy Mar 11 '20 at 16:40
  • Ah. What were the specific requirements of the exercise? Because it might be better to only define the methods as abstract, while in the interface, then make a separate class with the implementation. Also, you *are* able to make static interface methods (as all the other people pointed out), but it seems that that's not what you want to do. Your best option would be to instantiate a subclass and then use that to call the methods. – solonovamax Mar 11 '20 at 17:03
0

changing the method of by:

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;
    }

the errors switch to: ** 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:(46, 64) java: cannot find symbol symbol: method toList() location: interface java.util.Collection **

Archozy
  • 13
  • 4
0
  1. You declared of as non static method but try to access it statically.
    • Solution a: Call of on an instance.
    • Solution b(preferred): Declare of static (just replace default <ELEMENT_TYPE> Collection<ELEMENT_TYPE> of... by static <ELEMENT_TYPE> Collection<ELEMENT_TYPE> of...)
  2. see 1.
  3. toMap is not defined for Collection, probably best solution: Make of return ExtendedCollection (instead of "normal" Collection;)
  4. and 5. are related to/will be fixed by 3. - 6. by 1.

Yes, changing the return type to ExtendedCollection is not "that simple": here at least you have to initialize/provide one implementation, and yes if you don't choose a base class, which already provides add, you'd have to implement it:

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;
}

with:

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!
} 
xerx593
  • 12,237
  • 5
  • 33
  • 64
  • replacing Collection by ExtendedCollection seems to be the key but as I don't have implemented an add methods how would i do this ? – Archozy Mar 11 '20 at 16:39
  • it's almost this except that new MyExtendedCollectionImpl<>(); is not implemented as it is an interface. Do i have to reimplement every element of Collection ? – Archozy Mar 11 '20 at 16:53
  • nono, `...Impl` must be a class, no interface ..an interface, which has *no* implementor(somewhere) can be considered useless... – xerx593 Mar 11 '20 at 17:04