The Comparator interface required for Arrays.sort(T[],Comparator<T>) has a method that accepts two object references of the same type T, and returns an integer.
There is a bit of "magic" in method references. What Java does is wrap the method in such a way that it will fit the interface requirement.
The interface, of course, doesn't require a static method. But the wrapping can create a method that calls a static method, as in the Tutorial's first example:
public static int compareByAge(Person a, Person b) {
    return a.birthday.compareTo(b.birthday);
}
It wraps it in such a way that you get something similar to
new Comparator<Person>() {
    @Override
    public int compare(Person a, Person b) {
        return Person.compareByAge(a,b);
    }
}
Which satisfies the interface.
But in the example in the section "Reference to an Instance Method of an Arbitrary Object of a Particular Type", it wraps it differently. It needs a method that receives two strings, but it has a method that only receives one. This is how String::compareToIgnoreCase is defined:
public int compareToIgnoreCase(String str)
But in this case, it's an instance method. What Java does now is, because this method belongs to an object of type String, and accepts an object of type String it is easy to build a "wrap" around it that makes it into a method that accepts two objects, much like the lambda expression:
(String a, String b) -> {
    return a.compareToIgnoreCase( b );
}
Or, if we imagine a formal wrapping as a Comparator:
new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return a.compareToIgnoreCase(b);
    }
}
So, the fact that it's an instance method that belongs to type T, accepts type T and returns int allows Java to wrap it appropriately so it fits the Comparator interface.
But int compare(Demo2 o1, Demo2 o2) doesn't fit that pattern. It accepts two parameters. If a method accepts two parameters, it must be a static method to fit the wrapping rules - there is no way to pass the "this" object into the Comparator interface. So it tries to wrap it as a static method, and fails, as it is not a static method.
Bottom line: you got the error, because for this particular type of method reference, you need an instance method with only one parameter of the same type as the class.
As @Holger mentions in a comment, if you have a new class you are building, you shouldn't put a comparison method in it specifically for this sort of sorting task. If the class has a natural ordering, make it Comparable and use Arrays.sort(Object[]). If it doesn't, and you need to sort it sometimes based on any of its attributes, use a lambda expression or Comparator.comparing(Demo2::getI) which makes better use of an existing getter for the specific purpose of comparison.