在 Kotlin 中,Any 是所有非空类型的超类型。换句话说,Any 是 Kotlin 类型系统的根类型。它类似于 Java 中的 Object 类,但有一些重要的区别。
- Nullable和非Nullable:
Any是非空类型,这意味着它不能持有null值。如果你想表示可以为null的任意类型,可以使用Any?,即Any的可空版本。 - Smart Cast: 当你在代码中使用
is操作符检查类型并进入分支时,Kotlin 能够智能地将实例转换为相应的类型。这使得在分支内部可以直接使用特定类型的成员。
fun example(anyValue: Any) {
if (anyValue is String) {
// 在这个分支中,anyValue 被智能转换为 String 类型
println(anyValue.length)
}
}
- Any 的成员函数:
Any类型提供了一些通用的成员函数,如equals()、hashCode()和toString()。这些函数被所有非空类型继承,因此你可以在任何非空类型的实例上使用它们。源码如下:
/**
* The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass.
*/
public open class Any {
/**
* Indicates whether some other object is "equal to" this one. Implementations must fulfil the following
* requirements:
*
* * Reflexive: for any non-null value `x`, `x.equals(x)` should return true.
* * Symmetric: for any non-null values `x` and `y`, `x.equals(y)` should return true if and only if `y.equals(x)` returns true.
* * Transitive: for any non-null values `x`, `y`, and `z`, if `x.equals(y)` returns true and `y.equals(z)` returns true, then `x.equals(z)` should return true.
* * Consistent: for any non-null 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.
* * Never equal to null: for any non-null value `x`, `x.equals(null)` should return false.
*
* Read more about [equality](https://kotlinlang.org/docs/reference/equality.html) in Kotlin.
*/
public open operator fun equals(other: Any?): Boolean
/**
* Returns a hash code value for the object. The general contract of `hashCode` is:
*
* * Whenever it is invoked on the same object more than once, the `hashCode` method must consistently return the same integer, provided no information used in `equals` comparisons on the object is modified.
* * If two objects are equal according to the `equals()` method, then calling the `hashCode` method on each of the two objects must produce the same integer result.
*/
public open fun hashCode(): Int
/**
* Returns a string representation of the object.
*/
public open fun toString(): String
}
- Any 的使用场景:
Any类型在编写泛型代码时非常有用,因为你可以使用它表示任何非空类型的对象。同时,Any也可以用作函数的返回类型,以通用的方式返回不同类型的结果。
下面是一个简单的例子,演示了 Any 的基本用法:
fun printInfo(value: Any) {
println("Value: $value")
println("Type: ${value.javaClass.simpleName}")
}
fun main() {
val stringValue: Any = "Hello, Kotlin!"
val intValue: Any = 42
val doubleValue: Any = 3.14
printInfo(stringValue)
printInfo(intValue)
printInfo(doubleValue)
}
延伸: 关于代码中的 value.javaClass.simpleName 作用是 展示类名,对应源码如下:
/**
* Returns the runtime Java class of this object.
*/
public inline val <T : Any> T.javaClass: Class<T>
@Suppress("UsePropertyAccessSyntax")
get() = (this as java.lang.Object).getClass() as Class<T>
/**
* Returns the simple name of the underlying class as given in the
* source code. An empty string is returned if the underlying class is
* {@linkplain #isAnonymousClass() anonymous} or {@linkplain #isUnnamedClass() unnamed}.
* A {@linkplain #isSynthetic() synthetic class}, one not present
* in source code, can have a non-empty name including special
* characters, such as "{@code $}".
*
* <p>The simple name of an {@linkplain #isArray() array class} is the simple name of the
* component type with "[]" appended. In particular the simple
* name of an array class whose component type is anonymous is "[]".
*
* @return the simple name of the underlying class
* @since 1.5
*/
public String getSimpleName() {
if (isUnnamedClass()) {
return "";
}
ReflectionData<T> rd = reflectionData();
String simpleName = rd.simpleName;
if (simpleName == null) {
rd.simpleName = simpleName = getSimpleName0();
}
return simpleName;
}
输出结果
Value: Hello, Kotlin!
Type: String
Value: 42
Type: Integer
Value: 3.14
Type: Double
在这个例子中,printInfo 函数接受一个 Any 类型的参数,并打印该值以及其类型。在 main 函数中,我们传递了不同类型的值给 printInfo 函数,展示了 Any 的灵活性。