/
Any.scala
174 lines (164 loc) · 8.07 KB
/
Any.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/
package scala
/** Class `Any` is the root of the Scala class hierarchy. Every class in a Scala
* execution environment inherits directly or indirectly from this class.
*
* Starting with Scala 2.10 it is possible to directly extend `Any` using ''universal traits''.
* A ''universal trait'' is a trait that extends `Any`, only has `def`s as members, and does no initialization.
*
* The main use case for universal traits is to allow basic inheritance of methods for [[scala.AnyVal value classes]].
* For example,
*
* {{{
* trait Printable extends Any {
* def print(): Unit = println(this)
* }
* class Wrapper(val underlying: Int) extends AnyVal with Printable
*
* val w = new Wrapper(3)
* w.print()
* }}}
*
* See the [[https://docs.scala-lang.org/overviews/core/value-classes.html Value Classes and Universal Traits]] for more
* details on the interplay of universal traits and value classes.
*/
abstract class Any {
/** Compares the receiver object (`this`) with the argument object (`that`) for equivalence.
*
* Any implementation of this method should be an [[https://en.wikipedia.org/wiki/Equivalence_relation equivalence relation]]:
*
* - It is reflexive: for any instance `x` of type `Any`, `x.equals(x)` should return `true`.
* - It is symmetric: for any instances `x` and `y` of type `Any`, `x.equals(y)` should return `true` if and
* only if `y.equals(x)` returns `true`.
* - It is transitive: for any instances `x`, `y`, and `z` of type `Any` if `x.equals(y)` returns `true` and
* `y.equals(z)` returns `true`, then `x.equals(z)` should return `true`.
*
* If you override this method, you should verify that your implementation remains an equivalence relation.
* Additionally, when overriding this method it is usually necessary to override `hashCode` to ensure that
* objects which are "equal" (`o1.equals(o2)` returns `true`) hash to the same [[scala.Int]].
* (`o1.hashCode.equals(o2.hashCode)`).
*
* @param that the object to compare against this object for equality.
* @return `true` if the receiver object is equivalent to the argument; `false` otherwise.
*/
def equals(that: Any): Boolean
/** Calculate a hash code value for the object.
*
* The default hashing algorithm is platform dependent.
*
* Note that it is allowed for two objects to have identical hash codes (`o1.hashCode.equals(o2.hashCode)`) yet
* not be equal (`o1.equals(o2)` returns `false`). A degenerate implementation could always return `0`.
* However, it is required that if two objects are equal (`o1.equals(o2)` returns `true`) that they have
* identical hash codes (`o1.hashCode.equals(o2.hashCode)`). Therefore, when overriding this method, be sure
* to verify that the behavior is consistent with the `equals` method.
*
* @return the hash code value for this object.
*/
def hashCode(): Int
/** Returns a string representation of the object.
*
* The default representation is platform dependent.
*
* @return a string representation of the object.
*/
def toString(): String
/** Returns the runtime class representation of the object.
*
* @return a class object corresponding to the runtime type of the receiver.
*/
final def getClass(): Class[_] = sys.error("getClass")
/** Test two objects for equality.
* The expression `x == that` is equivalent to `if (x eq null) that eq null else x.equals(that)`.
*
* @param that the object to compare against this object for equality.
* @return `true` if the receiver object is equivalent to the argument; `false` otherwise.
*/
final def ==(that: Any): Boolean = this equals that
/** Test two objects for inequality.
*
* @param that the object to compare against this object for equality.
* @return `true` if !(this == that), false otherwise.
*/
final def != (that: Any): Boolean = !(this == that)
/** Equivalent to `x.hashCode` except for boxed numeric types and `null`.
* For numerics, it returns a hash value which is consistent
* with value equality: if two value type instances compare
* as true, then ## will produce the same hash value for each
* of them.
* For `null` returns a hashcode where `null.hashCode` throws a
* `NullPointerException`.
*
* @return a hash value consistent with ==
*/
final def ## : Int = sys.error("##")
/** Test whether the dynamic type of the receiver object has the same erasure as `T0`.
*
* Depending on what `T0` is, the test is done in one of the below ways:
*
* - `T0` is a non-parameterized class type, e.g. `BigDecimal`: this method returns `true` if
* the value of the receiver object is a `BigDecimal` or a subtype of `BigDecimal`.
* - `T0` is a parameterized class type, e.g. `List[Int]`: this method returns `true` if
* the value of the receiver object is some `List[X]` for any `X`.
* For example, `List(1, 2, 3).isInstanceOf[List[String]]` will return true.
* - `T0` is some singleton type `x.type` or literal `x`: this method returns `this.eq(x)`.
* For example, `x.isInstanceOf[1]` is equivalent to `x.eq(1)`
* - `T0` is an intersection `X with Y` or `X & Y: this method is equivalent to `x.isInstanceOf[X] && x.isInstanceOf[Y]`
* - `T0` is a union `X | Y`: this method is equivalent to `x.isInstanceOf[X] || x.isInstanceOf[Y]`
* - `T0` is a type parameter or an abstract type member: this method is equivalent
* to `isInstanceOf[U]` where `U` is `T0`'s upper bound, `Any` if `T0` is unbounded.
* For example, `x.isInstanceOf[A]` where `A` is an unbounded type parameter
* will return true for any value of `x`.
*
* This is exactly equivalent to the type pattern `_: T0`
*
* @note due to the unexpectedness of `List(1, 2, 3).isInstanceOf[List[String]]` returning true and
* `x.isInstanceOf[A]` where `A` is a type parameter or abstract member returning true,
* these forms issue a warning.
*
* @return `true` if the receiver object is an instance of erasure of type `T0`; `false` otherwise.
*/
final def isInstanceOf[T0]: Boolean = sys.error("isInstanceOf")
/** Forces the compiler to treat the receiver object as having type `T0`,
* even though doing so may violate type safety.
*
* This method is useful when you believe you have type information the compiler doesn't,
* and it also isn't possible to check the type at runtime.
* In such situations, skipping type safety is the only option.
*
* It is platform dependent whether `asInstanceOf` has any effect at runtime.
* It might do a runtime type test on the erasure of `T0`,
* insert a conversion (such as boxing/unboxing), fill in a default value, or do nothing at all.
*
* In particular, `asInstanceOf` is not a type test. It does **not** mean:
* {{{
* this match {
* case x: T0 => x
* case _ => throw ClassCastException("...")
* }}}
* Use pattern matching or [[isInstanceOf]] for type testing instead.
*
* Situations where `asInstanceOf` is useful:
* - when flow analysis fails to deduce `T0` automatically
* - when down-casting a type parameter or an abstract type member (which cannot be checked at runtime due to type erasure)
* If there is any doubt and you are able to type test instead, you should do so.
*
* Be careful of using `asInstanceOf` when `T0` is a primitive type.
* When `T0` is primitive, `asInstanceOf` may insert a conversion instead of a type test.
* If your intent is to convert, use a `toT` method (`x.toChar`, `x.toByte`, etc.).
*
* @throws ClassCastException if the receiver is not an instance of the erasure of `T0`,
* if that can be checked on this platform
* @return the receiver object.
*/
final def asInstanceOf[T0]: T0 = sys.error("asInstanceOf")
}