1

Given this class

public abstract class TLog<T> implements Serializable, Comparable<TLog> {
    private LocalDateTime moment;
    private String origin;
    private String type;
    private TableName table; // This is a simple enum
    private Comparator<TLog> comparator;
    private T message; // Message's type defined in child classes
    
    public TLog() {
        // comparator initialization
    }

    /* Getters & Setters omitted */

    @Override
    public int compareTo(TLog other) {
        return comparator.compare(this, other);
    }
}

This Comparator initialization does compile

this.comparator = Comparator.comparing(TLog::getMoment);
this.comparator = this.getComparator()
    .thenComparing(TLog::getTable)
    .thenComparing(TLog::getOrigin)
    .thenComparing(TLog::getType);

But this one doesn't

this.comparator = Comparator.comparing(TLog::getMoment)
    .thenComparing(TLog::getTable)
    .thenComparing(TLog::getOrigin)
    .thenComparing(TLog::getType);

And I don't understand why.
Here's the related compilation error on Comparator.comparing()

Non-static method cannot be referenced from a static context

Edit 1 : Hard-typing comparing does work

this.comparator = Comparator.<TLog, LocalDateTime>comparing(TLog::getMoment)
    .thenComparing(TLog::getTable)
    .thenComparing(TLog::getOrigin)
    .thenComparing(TLog::getType);

But I still don't get why my previous implementation doesn't work

IQbrod
  • 2,060
  • 1
  • 6
  • 28
  • 1
    Side note : I hope you are aware you are using raw `Log` type in member variable and in implementation of `Comparable`. – Michał Krzywański Sep 25 '20 at 14:46
  • @michalk can you explain how this does impact my implementation. I use generic type for non listed field (and not used in my comparator). – IQbrod Sep 25 '20 at 15:16
  • This example will not even compile as you have your `compareTo` method done wrong. It is not overriding the method from the `Comparable` interface. – Michał Krzywański Sep 25 '20 at 15:29
  • @michalk excuse me ? https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html Signature of `Comparable` is `int compareTo(T o)` – IQbrod Sep 25 '20 at 15:35
  • Now after you changed it it will at least compile. – Michał Krzywański Sep 25 '20 at 15:37
  • 1
    Why is this class generic when the type parameter `T` is not used anywhere? When you declare a type parameter, you must use it, otherwise, you’ll get the problems explained in [What is a raw type and why shouldn't we use it?](https://stackoverflow.com/q/2770321/2711488) – Holger Oct 06 '20 at 08:22
  • @Holger I omitted them for brevity, they are used in a field with a related getter & setter. – IQbrod Oct 06 '20 at 12:32
  • @Holger I know that default type is set to Object, my question here is on my `Comparator` which should work without any explicit declaration as it doesn't use my generic `T`. The first comparator will not compile without an explicit type declaration of (raw as it might be any type) `TLog`. – IQbrod Oct 06 '20 at 12:36
  • 1
    You *believe* “that default type is set to Object”, but that’s not what raw types are about. In fact there is not even a thing like “default type” in Java’s Generics. That’s why you should read the linked Q&A. Especially the point “*Essentially, raw types behaves just like they were before generics were introduced*”. It doesn’t matter whether it uses `T` or not. You can not expect generic type inference to work when you use a raw type. When the actual type argument doesn’t matter, specify a wildcard type, `>`, but don’t use a raw type. – Holger Oct 06 '20 at 12:47
  • @Holger specifying `Comparator>` doesn't fix my error, I still need to specify `comparing` type with `, LocalDateTime>comparing(TLog::getMoment)`. I admit that it's a cleaner implementation but it doesn't fix the compilation. I still do not understand why I have to hard-type `comparing()`. – IQbrod Oct 06 '20 at 12:52
  • 1
    `Comparator> comparator = Comparator.comparing(TLog>::getMoment) .thenComparing(TLog::getTable) .thenComparing(TLog::getOrigin) .thenComparing(TLog::getType);` – Holger Oct 06 '20 at 12:53
  • Nope `Unexpected wildcard` on `comparing(TLog>::getMoment)` – IQbrod Oct 06 '20 at 12:54
  • 1
    [No compiler errors](https://ideone.com/nS9kAC) – Holger Oct 06 '20 at 12:55
  • It does compile, Intellij highlight an error but there's none. You should post it as an answer :) – IQbrod Oct 06 '20 at 13:14

0 Answers0