添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
@Suppress




    
("NOTHING_TO_INLINE")
inline fun String?.isNotNullNorEmpty(): Boolean {
    //Expected performance impact of inlining 
    // 'public inline fun String?.isNotNullNorEmpty(): Boolean 
    // defined in com.example.warningsaserrorscases in file NothingToInlineWarnings.kt'
    // is insignificant. 
    // Inlining works best for functions with parameters of functional types
    return this != null && this.isNotEmpty()
  • Kotlin的inline关键字会将对应的方法内联到调用者的方法体,减少进栈出栈操作
  • inline最好的场景是处理函数类型参数,比如lambda
  • 刻意的inline可能导致方法体膨胀,增大class文件大小。
  • 处理这种警告,建议是去除inline关键字
  • 如果执意inline时,使用@Suppress("NOTHING_TO_INLINE")压制编译器警告
  • INACCESSIBLE_TYPE(不可访问的类型)

    public class RequestManager {
        public static RequestManager sInstance = new RequestManager();
        private static class TimelineRequest {
            public String from;
        public TimelineRequest getTimelineRequest() {
            return new TimelineRequest();
    
    fun testInaccessibleType() {
        //Type RequestManager.TimelineRequest! is inaccessible in this context
        // due to: private open class TimelineRequest defined
        // in com.example.warningsaserrorscases.RequestManager
        @Suppress("INACCESSIBLE_TYPE")
        RequestManager.sInstance.timelineRequest
    
  • 上述的testInaccessibleType无法访问TimelineRequest的属性和方法
  • 具体的解决办法,可以是设置TimelineRequest为public,而非private
  • 必要时可以使用@Suppress("INACCESSIBLE_TYPE")压制警告
  • UNCHECKED_CAST(未检查的类型转换)

    fun <T> Any.toType(): T? {
        //Unchecked cast: Any to T
        @Suppress("UNCHECKED_CAST")
        return this as? T
    
    //a better way
    inline fun <reified T> Any.toType(): T? {
        return if (this is T) {
        } else {
    

    WHEN_ENUM_CAN_BE_NULL_IN_JAVA(Enum 可能为null)

    fun testEnum1() {
        //Enum argument can be null in Java, but exhaustive when contains no null branch
        when(SeasonUtil.getCurrentSeason()) {
            Season.SPRING -> println("Spring")
            Season.SUMMER -> println("Summer")
            Season.FALL -> println("Fall")
            Season.WINTER -> println("Winter")
            //else -> println("unknown")
    fun testEnum2() {
        //Enum argument can be null in Java, but exhaustive when contains no null branch
        @Suppress("WHEN_ENUM_CAN_BE_NULL_IN_JAVA")
        when(SeasonUtil.getCurrentSeason()) {
            Season.SPRING -> println("Spring")
            Season.SUMMER -> println("Summer")
            Season.FALL -> println("Fall")
            Season.WINTER -> println("Winter")
    fun testParameterNameChangedOnOverride() {
        // The corresponding parameter in the supertype 'OnViewClickedListener'
        // is named 'viewId'.
        // This may cause problems when calling this function with named arguments.
        object : OnViewClickedListener {
            override fun onViewClicked(@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") id: Int) {
                println("onViewClicked id=$id")
        run {
            //Name shadowed: message
            @Suppress("NAME_SHADOWING") val message = "Hello World"
            println(message)
    
  • 当run方法后面的lambda中的message与testNameShadowing的message命名一致时,就发生了所谓的Name shadowing(命名遮挡)
  • Name shadowing很容易导致问题,且排查起来不易察觉。
  • 建议主动通过命名差异来解决这个问题
  • 不建议压制警告
  • Uncessary cases (不必要的编码场景)

    UNNECESSARY_SAFE_CALL(不必要的安全调用)

    fun testUnnecessarySafeCall(message: String) {
        @Suppress("UNNECESSARY_SAFE_CALL")
        println(message?.toIntOrNull())
    
    fun testSenselessComparison(message: String) {
        //Condition 'message != null' is always 'true'
        @Suppress("SENSELESS_COMPARISON")
        if (message != null) {
    
    fun testUncessaryNotNullAssertion(message: String) {
        //Unnecessary non-null assertion (!!) on a non-null receiver
        // of type String
        @Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
        println(message!!.toIntOrNull())
    
    fun testUselessIsCheck(message: String) {
        //Check for instance is always 'true'
        @Suppress("USELESS_IS_CHECK")
        if (message is String) {
    
    fun testVariableWithRedundantInitializer() {
        //Variable 'message' initializer is redundant
        @Suppress("VARIABLE_WITH_REDUNDANT_INITIALIZER") var message: String? = null;
        message = System.currentTimeMillis().toString()
        println(message)
    
    fun testGetDrawable(context: Context) {
        @Suppress("DEPRECATION")
        context.resources.getDrawable(R.mipmap.ic_launcher)
    

    建议的方法是寻找替代弃用方法的其他方法,以getDrawable为例,我们可以使用

  • ContextCompat.getDrawable(getActivity(), R.drawable.name);
  • ResourcesCompat.getDrawable(getResources(), R.drawable.name, null);
  • ResourcesCompat.getDrawable(getResources(), R.drawable.name, anotherTheme);
  • 必要时可以选择压制警告
  • unsued cases(开发者编码没有用到的情况)

    Parameter ‘extra’ is never used(参数没有使用)

    fun showMessage(message: String, extra: String?) {
        println(message)
    
  • 移除extra参数
  • 方法中使用extra参数
  • 使用@Suppress("UNUSED_PARAMETER")压制警告
  • Parameter ‘index’ is never used, could be renamed to _(匿名参数没有使用,可以使用占位符)

    fun forEachList() {
        listOf<String>("Hello", "World").forEachIndexed { index, s ->
            println(s)
    
    fun unusedVariable() {
        @Suppress("UNUSED_VARIABLE") val currentTimeStamp = System.currentTimeMillis()
        println("unusedVariable")
    
    fun testUnusedValue() {
        // The value '"Hello"' assigned to 'var message: String?
        // defined in com.example.warningsaserrorscases.test' is never used
        @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") var message: String? = null
        @Suppress("UNUSED_VALUE")
        message = "Hello"
    
  • 不建议滥用,因优先考虑其他的更好的解决问题的方式
  • 及时使用一定要限定最小作用范围,通常的选择范围尽量限制在变量(variable),参数(parameter)或者语句(statement)上。
  • 上面代码中出现了很多@Suppress主要目的是显示警告的名称,而不是提倡大家使用压制的方式处理警告。
  • 为 Kotlin 项目设置编译选项
  • 使用Kotlin Reified 让泛型更简单安全
  • 更多Kotlin优质内容
  •