Object etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Object etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

24 Şubat 2020 Pazartesi

Object.equals metodu

Giriş
Açıklaması şöyle. Eğer bu metod override ediliyorsa, hashCode() metodu da mutlaka override edilmeli.
  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x, x.equals(null) should return false.
Örnek
Şu satırı dahil ederiz.
import org.apache.commons.lang.builder.EqualsBuilder;
Şöyle yaparız.
class Employee{
  int id;
  ...

  @Override
  public boolean equals(Object obj){      
    return EqualsBuilder.reflectionEquals(this, obj);   
  }
}
Dikkat Edilecek Noktalar

1.  Principle of Least Astonishment
Eğer equals() metodu kafa karışıklığına sebep oluyorsa karışıklığa sebep olan kodu farklı bir metod içine taşımak daha iyi olabilir.

Örnek
Elimizde şöyle bir kod olsun. Burada equals() metodu bir çeşit logic içeriyor görünüyor.
Address a1 = new Address("123","000000-0","John Street","SpringField");
Address a2 = new Address("123","000000-0","John St.","SpringField");
assert a1.equals(a2); // Are abbreviations the same address?
Daha anlaşılır olsun diye şöyle yaparız.
Address a1 = new Address("123","000000-0","John Street","SpringField");
Address a2 = new Address("123","000000-0","John St.","SpringField");

System.out.print(a1.equals(a2)); // false;
System.out.print(a1.isSameLocation(a2)); // true;
Şöyle yaparız.
ector3 v1 = new Vector3(1.000001f, 1.0f, 1.0f);
Vector3 v2 = new Vector3(1.0f, 1.0f, 1.0f);

System.out.print(v1.equals(v2)); // false;
System.out.print(v1.isInRangeOf(v2, 0.01f)); // true;


6 Şubat 2020 Perşembe

Object Sınıfı

Giriş
Tüm sınıflar otomatik olarak bu sınıftan kalıtırlar ancak Object sınıfı başka bir sınıftan kalıtamaz. Açıklaması şöyle.
The extends clause must not appear in the definition of the class Object, or a compile-time error occurs, because it is the primordial class and has no direct superclass.
Bir başka açıklama şöyle
Each class except Object is an extension of (that is, a subclass of) a single existing class (§8.1.4) and may implement interfaces (§8.1.5).
equals metodu
Object.equalsmetodu yazısına taşıdım.

finalize metodu - Kullanmayın
İmzası şöyle
protected void finalize() throws Throwable {}
Şeklen şöyle
Finalization işlemini tek bir thread yapar. Açıklaması şöyle
The finalization queue is processed by a single thread in the JVM and that thread has a lower priority than other threads. As a result the finalizer thread may be slow to process the queue. Other factors may contribute to a backlog of objects consuming native memory too such as

- objects that reference other object that need to be finalized have not been GC’d yet
- some items in the finalization queue take a long time to finalize
- items are being added to the finalization queue at a higher rate than they are being processed
Java 18'den itibaren bu metod artık kaldırılıyor.  Açıklaması şöyle
JEP 421 announces the end of Java Finalizers. Adios to an ancient Java feature, born together with Java 1.0 and its Garbage Collector.
Java 18 ile gelen değişiklikler şöyle
What will actually change in the JDK 18
1- It will be added a new command-line option to disable finalization at runtime. This command will be useful to developers to test, in a protected environment, if the application will behave correctly also with finalizers shut down.
2- All finalizers in the standard Java API will be terminally deprecated (forRemoval=true)
3- A new “JDK.Finalizer” statistic will be added inside the JFR Java Flight Recorder
Her sınıf bu metoda sahiptir ancak kalıtan sınıflarda override edilmemesi yönünde ciddi uyarılar var.
Normalde bu metodu JVM çağırır ve tek bir kere çağırır. Açıklaması şöyle
The finalize method is never invoked more than once by a Java virtual machine for any given object.
Bu metodu kendimiz çağırsak bile JVM Garbage Collection esnasında yine çağırabilir. Bu metodu override eden nesneler Garbage Collection işini yavaşlatır. Açıklaması şöyle.
...instances that are collected by the finalizers are collected outside the scope of the JVM GC collection algorithms using a separate queue.
Dolayısıyla Effective Java kitabındaki şu uyarıya dikkat etmek gerekiyor.
There is a severe performance penalty for using finalizers.
Eğer bu metod içinden exception fırlatılırsa JVM çökmez. Açıklaması şöyle.
Any exception thrown by the finalize method causes the finalization of this object to be halted, but is otherwise ignored.
Bu kadar uyarıya rağmen kullanmak istersek bazı örnekler aşağıda

Örnek
Şöyle yaparız
public class ResourceHandler {
    
  private Resource resource;

  public ResourceHandler() {
    // Acquire the resource when an instance is created.
    resource = new Resource();
  }

  public void doWork() {
    // Perform some operations using the resource.
    resource.use();
  }

  // Destructor method to release the resource.
  @Override
  protected void finalize() {
    resource.close();
  }
}
Örnek
Şöyle yaparız
@Override
protected void finalize() throws Throwable {
  // closing resources here.... 
  super.finalize();
}
Örnek
Bazı yanlış örnekler şöyle. Burada silinmesi gereken nesne tekrar canlandırılıyor.
public class Resurrected {

  private static final Set<Resurrected> resurrected = new HashSet<>();

  @Override
  protected void finalize() throws Throwable {
    resurrected.add(this); // Resurrect the object by creating a new reference 
  }
}
getClass metodu
Açıklaması şöyle
getClass() always returns the runtime class of this Object. The returned Class object is the object that is locked by static synchronized methods of the represented class.
Elimizde bir kalıtım olsun.
class Person {

}

class Employee extends Person {

}
Şöyle yaparız.
Employee e = new Employee();
Person p = (Person) e;
System.out.println(p.getClass());
Çıktı olarak Employee alırız.

hashCode metodu
Şu satırı dahil ederiz.
import org.apache.commons.lang.builder.HashCodeBuilder;
Şöyle yaparız.
class Employee{
  int id;
  ...

  @Override
  public int hashCode(){      
    return HashCodeBuilder.reflectionHashCode (this);
  }
}