最近我们将我们的一个枚举类升级为带有对象作为子类的密封类,因此我们可以进行另一层抽象来简化代码.但是我们不能再通过Enum.values()函数获取所有可能的子类,这很糟糕,因为我们非常依赖于该功能.有没有办法用反射或任何其他工具检索此类信息?
PS:手动将它们添加到阵列是不可接受的.目前有45个,并计划增加更多.
这就是我们的密封类的样子:
sealed class State
object StateA: State()
object StateB: State()
object StateC: State()
....// 42 more
Run Code Online (Sandbox Code Playgroud)
如果有值集合,它将采用以下形状:
val VALUES = setOf(StateA, StateB, StateC, StateC, StateD, StateE,
StateF, StateG, StateH, StateI, StateJ, StateK, StateL, ......
Run Code Online (Sandbox Code Playgroud)
当然没有人想要保持这样的怪物.
我正在学习kotlin,但我很失望,我无法比较两个弦乐.
比较的正确方法是什么.
btn_login.setOnClickListener {
val login = input_email.text.trim()
val pass = input_password.text.trim()
if( login.equals( pass ) ){
startActivity<MainActivity>()
}
if (login?.equals(other = pass)){
startActivity<MainActivity>()
}
if (login == pass){
startActivity<MainActivity>()
}
}
Run Code Online (Sandbox Code Playgroud)
今天我正在Closeablekotlin中实现一个,就像我过去在java中所做的那样,我希望finalize()在客户端代码忘记关闭它的情况下实现一个最后的回退,使得关键资源无法回收.尽管这种回退不可靠,但我认为这种资源至关重要,足以增加这种后备.但是,kotlin.Any没有声明一个finalize方法,这意味着我不能简单地这样做:
class Resource: Closeable {
fun close() {}
override fun finalize() { close()}
}
Run Code Online (Sandbox Code Playgroud)
这不好,至少没有它应该的那么好.现在我恢复普通Java作为解决方法.有谁知道如何在纯Kotlin中做到这一点?
PS:我目前的解决方法:
FinalizedCloseable.java:
public abstract class FinalizedCloseable implement Closeable {
@Override protected void finalize() { close(); }
}
Run Code Online (Sandbox Code Playgroud)
科特林:
class Resource: FinalizedCloseable(), Closeable {
fun close() {}
override fun finalize() { close()}
}
Run Code Online (Sandbox Code Playgroud)
但是这种解决方法需要一个超类.如果下次我的其他人Resource已经有了一个超类,那么如果没有很多样板,这种解决方法将无法工作.
编辑:现在我知道如何实现finalize(),但IDEA kotlin插件不够聪明,不知道这是一个终结器,因此用一些警告标记它.经过一段时间的努力,我发现如何压制这些警告,我想分享它:
class C {
@Suppress("ProtectedInFinal", "Unused") protected fun finalize() {}
}
Run Code Online (Sandbox Code Playgroud) 例如:
v1?.apply {
v2?.apply {
call(this, target, outerThis);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是如何引用"outerThis"?谢谢你的帮助.
是编译器还是运行时执行自动装箱/拆箱?
请考虑以下示例:
public Integer get() {
return 1; //(1)
}
Run Code Online (Sandbox Code Playgroud)
在(1)处,原始整数值将被转换为类似的东西new Integer(1)并返回.这实际上是一种被称为自动拳击的隐形因素,但谁会这样做呢?编译器还是JVM?
我刚开始学习ASM,这样的拳击问题让我很困惑.
就在不久前,当我探索Kotlin github回购时,我发现了一些有趣的东西:Kotlin现在似乎有一个标题关键字.
open header class ArrayList<E> : MutableList<E> {
//...
header inline fun <reified T> Array<out T>?.orEmpty(): Array<out T>
Run Code Online (Sandbox Code Playgroud)
这是什么意思?它是一些公共可用功能还是内部功能来帮助stdlib开发?
编辑:似乎有一个impl关键字与标题一起使用.那是什么?
因此,我正在尝试编写一个非常简单的 Android 应用程序,当按下按钮时,它会从 URL 获取响应。kotlin Android 扩展已被宣传为 Java 中所需样板文件的直接替代品,所以我尝试了一下。到目前为止,这是我尝试过的:
package com.example.susemihl.myapplication
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.runBlocking
import java.net.URL
suspend fun fetch_url(url: String): String {
return URL(url).readText()
}
fun fetch_async(url: String, view: TextView) = runBlocking {
val result = async(CommonPool) { fetch_url(url) }
view.setText(result.await())
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainTextView.setText("Hello there.")
mainButton.setOnClickListener {
mainButton.setText("Check again.")
fetch_async("https://random-app.appspot.com/",
mainTextView)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这间歇性地起作用,但现在完全被破坏了。单击按钮没有任何响应。打印调试显示线程已执行,但似乎挂在 readText() 调用上。我在这里做错了什么愚蠢的事情吗?
我有一些旧的软件包,没有package-info.java。由于某种原因,我需要package-info.javas为他们创建任务,我发现任务真的很无聊,因为在Eclipse中没有捷径可以做到这一点。我必须手动使用该New > File过程创建文件,然后手动键入那些软件包名称。
Eclipse中是否有执行此任务的捷径?
我以为我会在我们的Android项目的gradle构建脚本中用Kotlin替换groovy,这样我就可以开始学习Kotlin了,但是遇到的第一个问题是试图寻找可以替代XmlSlurper和MarkupBuilder的类或库。有人可以建议要使用的图书馆或班级吗?
def entries = new XmlSlurper().parse("${projectDir}/src/release/res/values/app_settings.xml")
def fileLocation = "${projectDir}/src/debug/res/xml/env_prod.xml"
println "XML file location = ${fileLocation}"
def writer = new FileWriter(new File(fileLocation))
def xmlOut = new MarkupBuilder(writer)
xmlOut.mkp.xmlDeclaration(version: "1.0", encoding: "utf-8")
xmlOut.Environment {
entries.string.each {
def name = it.@name.toString()
def body = it.text()
if (name.startsWith('default_')) {
// don't copy production omniture when we're doing local testing!
name = name.replace('default_', '').toUpperCase()
xmlOut.entry(['name' : name], body)
}
}
}
Run Code Online (Sandbox Code Playgroud) var filename = "blesson.txt"
var wallpaperDirectory = File("/sdcard/Wallpaper")
wallpaperDirectory.mkdirs()
val outputFile = File(wallpaperDirectory, filename)
val fos = FileOutputStream(outputFile)
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用Kotlin在Android设备上创建新目录,但是该功能mkdirs()不起作用。
var filename = "blesson.txt"
var wallpaperDirectory = File(Environment.getExternalStorageDirectory().absolutePath)//("/sdcard/Wallpaper")
wall
val outputFile = File(wallpaperDirectory, filename)
val fos = FileOutputStream(outputFile)
Run Code Online (Sandbox Code Playgroud)
我也尝试过,它没有建立新目录,欢迎任何帮助
我有一个类,它是字符串的解析结果,因此我必须强制执行toString()以返回该源字符串而不是那些已解析的值.它还具有自定义equals()/ hashCode()机制.将其标记为数据类还有什么好处?
我的一位同事决定宣布一些这样的API代码:
public interface Filter<T> {
/**
* Test whether the given input is valid.
* @param input the input
* @return null for neutral, {@code Boolean.TRUE} for accepted and {@code Boolean.FALSE} for rejected.
*/
Boolean apply(T input);
}
Run Code Online (Sandbox Code Playgroud)
这个想法引发了对IRC的战争.虽然有些人提倡这种Boolean方法,但其他人认为这是不好的做法,应该使用三个元素的枚举来表示个体状态,如下所示:
public interface Filter<T> {
Result apply(T input);
enum Result {
ACCEPT, UNKNOWN, DENIED;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,在性能,可读性,可维护性方面,或者,如果真的重要,那么代码越少,生产中的最佳实践是什么?
编辑:在这里,接受,未知(或中立),拒绝(或拒绝)是@erickson的意思.如果你感到困惑,如果你感到困惑,请参考他的anwser.
在回应"搁置"时,我澄清说我的问题主要涉及:*是否有明确的约定?*这是接受anwser的原因
kotlin ×9
java ×4
android ×2
apply ×1
autoboxing ×1
data-class ×1
eclipse ×1
finalize ×1
groovy ×1
lambda ×1
package-info ×1