16 Eylül 2019 Pazartesi

Method Reference

Giriş
Açıklaması şöyle
Almost in all cases we should use a method reference instead of the equivalent lambda. The reason for this is most of the time it increases the readability. 
Grameri şöyledir.
MethodReference:
  ExpressionName :: [TypeArguments] Identifier 
  ReferenceType :: [TypeArguments] Identifier 
  Primary :: [TypeArguments] Identifier 
  super :: [TypeArguments] Identifier 
  TypeName . super :: [TypeArguments] Identifier 
  ClassType :: [TypeArguments] new 
  ArrayType :: new
Method Reference FunctionSupplier, BiPredicate ile kullanılabilir.

Kullanım Şekli
4 kullanım şekli var. Bunlar şöyle
Kind                                               Example
========================================================================================
Reference to a static method                      | ContainingClass::staticMethodName
--------------------------------------------------+--------------------------------------
Reference to an instance method of a 
particular object                                 | containingObject::instanceMethodName
--------------------------------------------------+--------------------------------------
Reference to an instance method of an
arbitrary object                                  | ContainingType::methodName
of a particular type                              |
--------------------------------------------------+--------------------------------------
Reference to a constructor                        | ClassName::new
=========================================================================================
new metod
Method Reference - Reference to Constructor

static metod
Örnek
static üye metod için şöyle yaparız.
import com.example.MyClass;

someStream.map(MyClass::myStaticMethod)
Örnek
Elimizde şöyle bir kod olsun
interface SomeTest <T>
{
  boolean test(T n, T m);
}

class MyClass
{
  static <T> boolean myGenMeth(T x, T y)
  {
    boolean result = false;
    // ...
    return result;
  }
}
Generic kod olduğu için şöyle yaparız. Derleyiciye yardım olma işine  type witness deniliyor.
SomeTest <Integer> mRef = MyClass :: <Integer> myGenMeth;

Type İçin instance metod
Örnek
Şöyle yaparız.
Predicate<List<String>> p = List::isEmpty;
Object İçin instance metod
Method Reference - Object İçin instance metod yazısına taşıdım.

Diğer

1. Method Reference ve  Lambda Farkı
Method Reference ile şöyle yaparız
JCacheTimeZoneCache::new
Lambda ile şöyle yaparız
() -> new JCacheTimeZoneCache()
Lambda kullanan kod Classloader'ı kullanarak hemen sınıfı yüklemez.

2. Equality
Açıklaması şöyle.
JLS makes no promises about identity or equality of what you get out of method reference expressions.
Örnek
Şöyle yaparız.
Object obj = new Object();

IntSupplier foo = obj::hashCode;
IntSupplier bar = obj::hashCode;

System.out.println(foo == bar);  // false

System.out.println(foo.equals(bar));  // false   
Örnek
Şöyle yaparız.
Object object = ...;
Supplier<String> s1 = object::toString;
Supplier<String> s2 = object::toString;
System.out.println(s1.equals(s2));
3. toString
Açıklaması şöyle. Method Reference nesnesinin toString() metodunun ne olacağı tanımlı değil.
Once a method reference is used you'll have an implementation of the functional interface that you requested, but basically all the specifics of that object as undefined (or implementation-defined to be precise).

The spec doesn't say anything about it being a separate object, what its toString() has to be or what else you can do with it. It's a Supplier<?> and basically nothing else.

The same thing applies to lambda expressions.
Örnek
Elimizde şöyle bir kod olsun.
public class HelloWorld {
  public static void main(String... args){
    final String string = "a";
    final Supplier<?> supplier = string::isEmpty;
    System.out.println(supplier);
  }
}
Çıktı olarak şunu alırız.
HelloWorld$$Lambda$1/471910020@548c4f57

Hiç yorum yok:

Yorum Gönder