I'm learning Java 8 with Lambda and Streams and method reference. And I have a question regarding the example below.

```
Optional<String> s = Optional.of("test");
System.out.println(s.map(String::toUpperCase).get());

```

I don't understand how is it possible to use `String::toUpperCase` as an input for this `map()` method.
This is the method implementation:

```
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent()) {
        return empty();
    } else {
        return Optional.ofNullable(mapper.apply(value));
    }
}

```

So it requires a Function interface, and it has this apply() method: `R apply(T t);` This method has an input argument.

And `toUpperCase()` method doesn't have any argument:

```
public String toUpperCase() {
    return toUpperCase(Locale.getDefault());
}

```

I know that if the abstract method has one argument then the implemented method should have one argument of the same type. How can `toUpperCase()` method implement `apply(T t)` method from Function interface?

I try to recreate the same conditions:

I create a functional interface:

```
public interface Interf {
    String m1(String value);
}

```

Then I create a class with the method reference for m1():

```
public class Impl {
    public String value;

    public String toUpp() {
        return value.toUpperCase();
    }
}

```

And here is a class for test:

```
public class Test {
    public static void main(String[] args) {
        Interf i = String::toUpperCase;
        System.out.println(i.m1("hey"));

        Interf i1 = Impl::toUpp;
        System.out.println(i.m1("hello"));
    }
}

```

There is no issue at this statement: `Interf i = String::toUpperCase;` but there is a compilation error on this line: `Interf i1 = Impl::toUpp;`. It says:

```none
Non-static method cannot be referenced from a static context

```

But `toUpperCase()` is also a non-static method. And even if I make the `toUpp()` static, it is still not working, it is working only if I add a String argument as an input argument for `toUpp()`. But then why is it working for `String::toUpperCase` ?