与扩展方法类似,扩展属性当然也不是真正添加进了原类。
扒开糖衣看看kotlin扩展属性实现原理。
给Date类添加formatDate属性
val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
val Date.formatDate: String
get() = sdf.format(this.time)
调用处
val formatDate = Date().formatDate
反编译成java
@NotNull
public static final SimpleDateFormat getSdf() {
return sdf;
}
@NotNull
public static final String getFormatDate(@NotNull Date $receiver) {
Intrinsics.checkParameterIsNotNull($receiver, "receiver$0");
String var10000 = sdf.format($receiver.getTime());
Intrinsics.checkExpressionValueIsNotNull(var10000, "sdf.format(this.time)");
return var10000;
}
静态方法,将调用者当做参数传入。好处就是和扩展方法一样,写起来像是原类调用。
还可以定义var可变类型的扩展属性
var TextView.value: CharSequence
get() = this.text
set(value) {
this.text = value
}
注意set(value) 本质上没有地方存值,还是在操作this原类的属性。反编译成java,一目了然。
@NotNull
public static final CharSequence getValue(@NotNull TextView $receiver) {
Intrinsics.checkParameterIsNotNull($receiver, "receiver$0");
CharSequence var10000 = $receiver.getText();
Intrinsics.checkExpressionValueIsNotNull(var10000, "this.text");
return var10000;
}
public static final void setValue(@NotNull TextView $receiver, @NotNull CharSequence value) {
Intrinsics.checkParameterIsNotNull($receiver, "receiver$0");
Intrinsics.checkParameterIsNotNull(value, "value");
$receiver.setText(value);
}
搞点骚操作,int扩展属性
val sdf: SimpleDateFormat
get() = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val Int.daysAgo: String
get() = Calendar.getInstance().run {
this.add(Calendar.DAY_OF_YEAR, -this@daysAgo)
sdf.format(this.timeInMillis)
}
val Int.daysLater: String
get() = Calendar.getInstance().run {
this.add(Calendar.DAY_OF_YEAR, +this@daysLater)
sdf.format(this.timeInMillis)
}
val Int.weekAgo: String
get() = Calendar.getInstance().run {
this.add(Calendar.WEEK_OF_YEAR, -this@weekAgo)
sdf.format(this.timeInMillis)
}
val Int.weekLater: String
get() = Calendar.getInstance().run {
this.add(Calendar.WEEK_OF_YEAR, +this@weekLater)
sdf.format(this.timeInMillis)
}
val Int.monthAgo: String
get() = Calendar.getInstance().run {
this.add(Calendar.MONTH, -this@monthAgo)
sdf.format(this.timeInMillis)
}
val Int.monthLater: String
get() = Calendar.getInstance().run {
this.add(Calendar.MONTH, +this@monthLater)
sdf.format(this.timeInMillis)
}
val Int.yearAgo: String
get() = Calendar.getInstance().run {
this.add(Calendar.YEAR, -this@yearAgo)
sdf.format(this.timeInMillis)
}
val Int.yearLater: String
get() = Calendar.getInstance().run {
this.add(Calendar.YEAR, +this@yearLater)
sdf.format(this.timeInMillis)
}
//打印log看效果
inline fun <reified T> T.ktxLog(msg: String) = Log.d(T::class.java.name, msg)
调用处
ktxLog(3.daysAgo)
ktxLog(3.daysLater)
ktxLog(3.weekAgo)
ktxLog(3.weekLater)
ktxLog(3.monthAgo)
ktxLog(3.monthLater)
ktxLog(3.yearAgo)
ktxLog(3.yearLater)
log
2020-01-09 11:06:01.589 11698-11698/HomeActivity: 2020-01-06
2020-01-09 11:06:01.592 11698-11698/HomeActivity: 2020-01-12
2020-01-09 11:06:01.595 11698-11698/HomeActivity: 2019-12-19
2020-01-09 11:06:01.599 11698-11698/HomeActivity: 2020-01-30
2020-01-09 11:06:01.605 11698-11698/HomeActivity: 2019-10-09
2020-01-09 11:06:01.608 11698-11698/HomeActivity: 2020-04-09
2020-01-09 11:06:01.611 11698-11698/HomeActivity: 2017-01-09
2020-01-09 11:06:01.615 11698-11698/HomeActivity: 2023-01-09
扩展属性也可以搞一堆操作玩出花样。
网友评论