Java Basic系列之(五):Object

Object中的equals()

equals

官方文档
public boolean equals(Object obj)
Indicates whether some other object is “equal to” this one.
The equals method implements an equivalence relation on non-null object references:

  • 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.

The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

Java中的相等比较

java中的数据类型,可分为两类:
1. 基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean
他们之间的比较,应用双等号(==),比较的是他们的值。
2. 复合数据类型(类)
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。

变长参数

{…1, 2, 3} => [1, 2, 3]
可变参数==数组参数? 在带可变参数的方法体时,读取可变参数列表时,就是以数组的方式来读取;

  • 带可变参数的方法可以传入一个数组参数,但带数组参数的方法却不能传入可变参数。
  • JDK不允许存在,带相同参数类型列表(Type List)的参数列表的方法在同一类中重载。
  • 当可变参数方法与不带参数的方法重载时,JDK默认调用的是无参数的方法。若类中没有定义无参数的方法,则会调用可变参数的方法。

https://docs.oracle.com/javase/8/docs/technotes/guides/language/varargs.html

  • In past releases, a method that took an arbitrary number of values required you to create an array and put the values into the array prior to invoking the method.
  • It is still true that multiple arguments must be passed in an array, but the varargs feature automates and hides the process. Furthermore, it is upward compatible with preexisting APIs.

类的初始化

  • 一个类在初始化的时候,会被分配一片内存地址,因此一个类的成员会被赋初始值。基本类型的初始值就是
Data Type Default Value (for fields)
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char ‘\u0000’
String (or any object) null
boolean false

- 进一步推导,数组在内存中是以对象的形式表示的。对象的字段在初始化的时候会被赋初始值。因此数组被声明长度后,里面的每个值都会被赋初始值。从内存的角度来看,声明一个带一定长度的数组之后,在内存中给它分配了一块内存地址。因此它是有值的。

代码块

在在类中直接定义没有任何修饰符、前缀、后缀的代码块即为构造代码块。我们明白一个类必须至少有一个构造函数,构造函数在生成对象时被调用。
1、 静态代码块,它是随着类的加载而被执行,只要类被加载了就会执行,而且只会加载一次,主要用于给类进行初始化。
2、 构造代码块,每创建一个对象时就会执行一次,且优先于构造函数,主要用于初始化不同对象共性的初始化内容和初始化实例环境。
3、 构造函数,每创建一个对象时就会执行一次。同时构造函数是给特定对象进行初始化,而构造代码是给所有对象进行初始化,作用区域不同。
通过上面的分析,他们三者的执行顺序应该为:静态代码块 > 构造代码块 > 构造函数。
4、 field的初始化顺序是由它在代码中的位置决定的。构造代码块一定是在构造函数之前执行。


public class Test {
    /**
     * 构造代码
     */
    {
        System.out.println("执行构造代码块...");
    }

    /**
     * 无参构造函数
     */
    public Test(){
        System.out.println("执行无参构造函数...");
    }

    /**
     * 有参构造函数
     * @param id  id
     */
    public Test(String id){
        System.out.println("执行有参构造函数...");
    }
}

Java中的Override重写与Overload重载

override priceples.

https://docs.oracle.com/javase/tutorial/java/IandI/override.html
Override:重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。

  • 参数列表必须完全与被重写方法的相同;
  • 返回类型必须完全与被重写方法的返回类型相同;
  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
  • 父类的成员方法只能被它的子类重写。
  • 声明为final的方法不能被重写。
  • 声明为static的方法不能被重写,但是能够被再次声明。
  • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
  • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
  • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
  • 构造方法不能被重写。
  • 如果不能继承一个方法,则不能重写这个方法。

https://www.geeksforgeeks.org/overriding-in-java/.
In any object-oriented programming language, Overriding is a feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its super-classes or parent classes. When a method in a subclass has the same name, same parameters or signature and same return type(or sub-type) as a method in its super-class, then the method in the subclass is said to override the method in the super-class.

Method overriding is one of the way by which java achieve Run Time Polymorphism.The version of a method that is executed will be determined by the object that is used to invoke it. If an object of a parent class is used to invoke the method, then the version in the parent class will be executed, but if an object of the subclass is used to invoke the method, then the version in the child class will be executed.In other words, it is the type of the object being referred to (not the type of the reference variable) that determines which version of an overridden method will be executed.

Dynamic Method Dispatch or Runtime Polymorphism in Java
Prerequisite: Overriding in java, Inheritance

Method overriding is one of the ways in which Java supports Runtime Polymorphism. Dynamic method dispatch is the mechanism by which a call to an overridden method is resolved at run time, rather than compile time.

When an overridden method is called through a superclass reference, Java determines which version(superclass/subclasses) of that method is to be executed based upon the type of the object being referred to at the time the call occurs. Thus, this determination is made at run time.
At run-time, it depends on the type of the object being referred to (not the type of the reference variable) that determines which version of an overridden method will be executed
A superclass reference variable can refer to a subclass object. This is also known as upcasting. Java uses this fact to resolve calls to overridden methods at run time.

Rules for method overriding:

  • Overriding and Access-Modifiers : The access modifier for an overriding method can allow more, but not less, access than the overridden method. For example, a protected instance method in the super-class can be made public, but not private, in the subclass. Doing so, will generate compile-time error.
  • Final methods can not be overridden : If we don’t want a method to be overridden, we declare it as final. Please see Using final with Inheritance .
  • Static methods can not be overridden(Method Overriding vs Method Hiding) : When you defines a static method with same signature as a static method in base class, it is known as method hiding.
    The following table summarizes what happens when you define a method with the same signature as a method in a super-class.
  • Private methods can not be overridden : Private methods cannot be overridden as they are bonded during compile time. Therefore we can’t even override private methods in a subclass.(See this for details).
  • The overriding method must have same return type (or subtype) : From Java 5.0 onwards it is possible to have different return type for a overriding method in child class, but child’s return type should be sub-type of parent’s return type. This phenomena is known as covariant return type.
  • Invoking overridden method from sub-class : We can call parent class method in overriding method using super keyword.
  • Overriding and constructor : We can not override constructor as parent and child class can never have constructor with same name(Constructor name must always be same as Class name).
  • Overriding and Exception-Handling : Below are two rules to note when overriding methods related to exception-handling.
  • Overriding and abstract method : Abstract methods in an interface or abstract class are meant to be overridden in derived concrete classes otherwise compile-time error will be thrown.
  • Overriding and synchronized/stricfp method : The presence of synchronized/stricfp modifier with method have no effect on the rules of overriding, i.e. it’s possible that a synchronized/stricfp method can override a non synchronized/stricfp one and vice-versa.

Overload:重载

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

  • 被重载的方法必须改变参数列表(参数个数或类型不一样);
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的检查异常;
  • 方法能够在同一个类中或者在一个子类中被重载。
  • 无法以返回值类型作为重载函数的区分标准。

你可能感兴趣的:(Java)