Kotlin 에서 협 변,역 변 과 변 하지 않 는 예제 에 대한 상세 한 설명

머리말
Kotlin 범 형의 기본 문법 은 자바 와 유사 하지만,형태 변화 가 안전 하기 때문에 자바 의,<?슈퍼 T>어댑터 형 변환 제약 이 아니 라 C\#와 유사 한 in,out 를 사용 하여 협동 과 역 변 을 지원 합 니 다.이 동시에 하위 유형 화,부모 유형 화 문 제 를 처리 하 는 것 을 피 할 수 있 습 니 다(즉,자바 범 형 에서 전형 적 인 List는 List의 하위 유형 이 아 닙 니 다).
기본 적 인 범 형 문법 은 공식 중국어 문 서 를 참고 할 수 있다.https://www.kotlincn.net/docs/reference/
범 형 실 삼 의 계승 관계 가 범 형 유형 에 미 친 영향
협 변:범 형 유형 과 실 삼 의 계승 관계 가 같다.
역 변:범 형 유형 과 실 삼 의 계승 관 계 는 상반 된다
변 하지 않 음:일반적인 유형 은 관계 가 없습니다.
협 변 점:반환 값 유형 은 범 형 매개 변수 유형 입 니 다.
역 변 점:입 참 유형 은 범 형 매개 변수 유형 입 니 다.
@UnsafeVariance:협 변 점 위반,컴 파일 러 에 게 괜찮다 고 말 하고 내 뜻 대로 실행 해.
1.범 형
무엇이 범 형 입 니까?범 화 된 유형 이나 유형의 추상,오리 유형(오리 처럼 보이 고 걸 어도 오리 처럼 보이 지만 오리 유형)이 정적 언어 에서 의 정적 실현
1.추상 류 는 이런 유형의 본질 이 고 무엇 입 니까?
2.인터페이스,관심 분야 가 무엇 을 할 수 있 는 지,행동 능력
두 가지 예 를 들다
두 수의 비교 크기

//         ,        a<b
//     Comparable        
fun<T:Comparable<T>> maxOf(a:T,b:T):T{
 return if (a<b) b else a
}
방법 호출

val a=2
val b=3
val maxOf = maxOf(2, 3)
 println("shiming "+maxOf)
출력 결과

 shiming 3
대비 할 수 있 는 능력 을 갖 추 게 하 다.

data class Complex(val a:Double,val b:Double):Comparable<Complex>{
 override fun compareTo(other: Complex): Int {
 return (value()-other.value()).toInt()
 }
 fun value():Double{
 return a*a+b*b
 }

 override fun toString(): String {
 return "$a*$a+$b*$b="+(a*a+b*b)
 }
}
방법 호출

 val Complex1=Complex(4.0,5.0)
 val Complex2=Complex(5.0,6.0)
 println("shiming Complex1="+Complex1)
 println("shiming Complex2="+Complex2)
 println("shiming"+Complex1.compareTo(Complex2))
출력 결과

04-16 11:22:10.824 26429-26429/com.kotlin.demo I/System.out: shiming Complex1=4.0*a+5.0*b=41.0
04-16 11:22:10.824 26429-26429/com.kotlin.demo I/System.out: shiming Complex2=5.0*a+6.0*b=61.0
04-16 11:22:10.824 26429-26429/com.kotlin.demo I/System.out: shiming-20
데모 테스트 결 과 를 통 해 범 형 은 당신 이 무엇 이 든 당신 이 무엇 을 할 수 있 는 지 에 만 달 려 있다 는 것 을 알 게 되 었 습 니 다.
여러 개의 일반적인 매개 변 수 를 정의 합 니 다.
kotlin 의 예

 (1..2).map { println("shiming $it=="+it) }

/**
 * Returns a list containing the results of applying the given [transform] function
 * to each element in the original collection. 
 (1..2).map        
 */
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
 return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
}
/** A function that takes 22 arguments. function      22.   23    */
public interface Function22<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, in P14, in P15, in P16, in P17, in P18, in P19, in P20, in P21, in P22, out R> : Function<R> {
 /** Invokes the function with the specified arguments. */
 public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20, p21: P21, p22: P22): R
}
kotlin 의 클래스 입력 범 형

data class ComplexNumber< T : Number>(val a:T,val b:T){
 override fun toString(): String {
 return "$a*$a+$b*$b"
 }
}
범 형의 실현 메커니즘.
위 범 형(자바,Kotlin)은 무엇 입 니까?컴 파일 이 끝나 자 범 형 은 사 라 졌 다.Martin Odersky 는 Typesafe 의 공동 창시자 이자Martin Odersky프로 그래 밍 언어의 발명자 이다.)

//                   ,  Java kotlin      object     
fun needList(list:List<Double>){
}
fun needList(list:List<Int>){
}
역 컴 파일 을 통 해 알 수 있 듯 이 와 조 는 나의 범 형 이 없어졌다.

 public static final void needList(@NotNull List list) {
  Intrinsics.checkParameterIsNotNull(list, "list");
 }

 public static final void needList(@NotNull List list) {
  Intrinsics.checkParameterIsNotNull(list, "list");
 }

컴 파일 통과 없 음
무엇이 진 범 형(C\#)입 니까?컴 파일 이 끝 났 습 니 다.아직 있 습 니 다.
이상 의 코드 를 C\#에 두 면 오류 가 발생 하지 않 습 니 다.이 유 는 C\#의 범 형 이 컴 파일 러 뿐만 아니 라 운행 기간 도 존재 하기 때 문 입 니 다.
java 1.5 에 만 있 는 일반적인 특성,현실 적 인 수요 에 시 달리 고 있 습 니 다!사용 하 는 사람 이 너무 많 지만 C\#첫 번 째 버 전도 범 형 이 없 지만 사용 하 는 사람 이 적어 서 C\#는 진짜 범 형 을 사용한다.
그러나 컴 파일 러 에서 일반적인 유형 을 얻 을 수 있 는 방법 이 있다.
reified 는 범 형 매개 변 수 를 구체화 시 키 고 inline 에서 kotlin 을 위 범 형 으로 정의 합 니 다.이 키 워드 를 호출 에 삽입 해 야 합 니 다.

//inline inline      (inline function)          ,
//                ,                 !
inline fun<reified T> getT(){
 println("shiming"+T::class.java)
}
호출

getT<String>()
getT<Double>()
//          ,   ,       ,         
  String var21 = "shiming" + String.class;
  System.out.println(var21);
  var21 = "shiming" + Double.class;
  System.out.println(var21);
얻다

04-16 15:28:59.775 31782-31782/com.kotlin.demo I/System.out: shimingclass java.lang.String
04-16 15:28:59.775 31782-31782/com.kotlin.demo I/System.out: shimingclass java.lang.Double
실제 업무 에 서 는 이렇게 쓸 수 있다.

data class Person(val name:String,val age:Int){
 //  ,  json   
 override fun toString(): String {
  return "{name="+"\""+name+"\","+"age="+age+"}"
 }
}

//     inline             
// reified        ,   inline  ,kotlin      ,                
inline fun <reified T> Gson.fromJson(json:String):T=fromJson(json,T::class.java)
//         json  ,  bean 
 val person=Person("shiming",20)
 println("shiming "+person)
 val toString = person.toString()
 val person1= Gson().fromJson<Person>(toString)
 println("shiming person1"+person1)

//             , java    ,     
  Person person = new Person("shiming", 20);
  String toString = "shiming " + person;
  System.out.println(toString);
  toString = person.toString();
  Gson $receiver$iv = new Gson();
  Person person1 = (Person)$receiver$iv.fromJson(toString, Person.class);
  String var25 = "shiming person1" + person1;
  System.out.println(var25);
구체 적 관계
f(⋅)는 역 변(contravariant)의 것 으로 A≤B 시 f(B)≤f(A)가 성립 된다.
f(⋅)는 협 변(covariant)의 것 으로 A≤B 시 f(A)≤f(B)가 성립 된다.
f(⋅)는 변 하지 않 는 다(invariant).A≤B 일 때 상기 두 식 은 모두 성립 되 지 않 는 다.즉,f(A)와 f(B)는 서로 상속 관계 가 없다.
협동 하여 변화 하 다
kotlin 에서 List 는 자바 의 List 가 아 닙 니 다.읽 기 전용 입 니 다.원본 코드 는 아래 List와 같 습 니 다.Out 을 보면 협동 적 이 고 읽 기 전용 입 니 다.List 에는 add 방법 이 없습니다.요 소 를 추가 할 수 없습니다.

//out    Number  Int   ,          
val numberList:List<Number> = listOf<Int>(1,58)
 public interface List<out E> : Collection<E> {
 // Query Operations
 override val size: Int

 override fun isEmpty(): Boolean
 //         ,          
 override fun contains(element: @UnsafeVariance E): Boolean
 override fun iterator(): Iterator<E>

 // Bulk Operations
 override fun containsAll(elements: Collection<@UnsafeVariance E>): Boolean

 // Positional Access Operations
 /**
  * Returns the element at the specified index in the list.、
         E
  */
 public operator fun get(index: Int): E

 // Search Operations
 /**
  * Returns the index of the first occurrence of the specified element in the list, or -1 if the specified
  * element is not contained in the list.
  */
 public fun indexOf(element: @UnsafeVariance E): Int

 /**
  * Returns the index of the last occurrence of the specified element in the list, or -1 if the specified
  * element is not contained in the list.
  */
 public fun lastIndexOf(element: @UnsafeVariance E): Int

 // List Iterators
 /**
  * Returns a list iterator over the elements in this list (in proper sequence).
  */
 public fun listIterator(): ListIterator<E>

 /**
  * Returns a list iterator over the elements in this list (in proper sequence), starting at the specified [index].
  */
 public fun listIterator(index: Int): ListIterator<E>

 // View
 /**
  * Returns a view of the portion of this list between the specified [fromIndex] (inclusive) and [toIndex] (exclusive).
  * The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa.
  *
  * Structural changes in the base list make the behavior of the view undefined.
  */
 public fun subList(fromIndex: Int, toIndex: Int): List<E>
}
역 변:Comparable 인터페이스

  //in    ,                       Any Int   
 val intComparable:Comparable<Int> = object :Comparable<Any>{
      override fun compareTo(other: Any): Int {
        return 0
      }
    }

public interface Comparable<in T> {
  public operator fun compareTo(other: T): Int
}
변 하지 않 음:MutableList 는 자바 의|Array List 에 해당 합 니 다.읽 을 수 있 고 쓸 수 있 으 며 가 변 적 이지 않 습 니 다.범 형 은 in 또는 out 이 없고 범 형의 계승 관계 도 구체 적 인 관계 가 없습니다.앞 에 있 는 하위 클래스 나 뒤에 있 는 하위 클래스 는 모두 성립 되 지 않 습 니 다.

public interface MutableList<E> : List<E>, MutableCollection<E> {
  override fun add(element: E): Boolean
  override fun remove(element: E): Boolean
  override fun addAll(elements: Collection<E>): Boolean
  public fun addAll(index: Int, elements: Collection<E>): Boolean
  override fun removeAll(elements: Collection<E>): Boolean
  override fun retainAll(elements: Collection<E>): Boolean
  override fun clear(): Unit
  public operator fun set(index: Int, element: E): E
  public fun add(index: Int, element: E): Unit
  public fun removeAt(index: Int): E
  override fun listIterator(): MutableListIterator<E>
  override fun listIterator(index: Int): MutableListIterator<E>
  override fun subList(fromIndex: Int, toIndex: Int): MutableList<E>
}
별 투영:항상 가장 안전 한 해결 방법 을 찾 습 니 다.안전 방식 은 범 형 유형 을 정의 하 는 이런 투영 입 니 다.이 범 형 유형의 모든 구체 적 인 사례 화 는 이 투영 의 하위 유형 이 될 것 입 니 다.
만약 에 범 형 유형 이 여러 가지 유형의 매개 변 수 를 가지 고 있다 면 모든 유형의 매개 변 수 는 단독으로 투영 할 수 있다.
예 를 들 어 유형 이interface Function <in T, out U>로 밝 혀 지면 다음 별 투영 을 상상 할 수 있다.Function<*, String> 표시Function<in Nothing, String>;Function<Int, >표시Function<Int, out Any?>;Function<, *> 표시Function<in Nothing, out Any?>.
별 이 비 치 는 곳

 //out    Number  Int   ,          
    val numberList:List<*> = listOf<Int>(1,58)
    val any = numberList[1] //   ,    
    //in    ,                      
    val intComparable:Comparable<*> = object :Comparable<Any>{
      override fun compareTo(other: Any): Int {
        return 0
      }
    }
    //   ,     Nothing
    intComparable.compareTo()

fun <T> hello(){

}
open class Hello<T>{

}
//           
class Hello33<T>
//          
class Hello2:Hello<Hello<*>>()
class Hello332:Hello<Hello33<*>>()
kotlin 에서 자바 클래스 를 호출 합 니 다.

    //          
 val raw:Raw<*> = Raw.getRaw()
public class Raw<T> {
  @Override
  public String toString() {
    return "   Raw";
  }
  public static Raw getRaw(){
    return new Raw();
  }
}
별 투영 이 안 되 는 곳.

    //    ,         ,                
//    val list1:MutableList<Number> = mutableListOf<Int>(1,5,4)
    list1.add(BigDecimal(1244444444))
//    val list2:MutableList<Int> = mutableListOf<Number>(1,5,4)

    //           
//    val numberList11d:List<*> = listOf<*>(1,58)
//
//    hello<*>()
//
//    val hello: Any = Hello<*>()
fun <T> hello(){

}
open class Hello<T>{

}
안 탁 중의 한 MvpDemo 는 별 투영 과 협 변 에 사용 되 었 습 니 다!

package com.kotlin.demo.star_demo
import org.jetbrains.annotations.NotNull
import java.lang.reflect.ParameterizedType

/**
 * author: Created by shiming on 2018/4/14 15:08
 * mailbox:[email protected]
 */
//Mvp   V      
interface IView<out P:Ipresenter<IView<P>>>{
  val presenter:P
}
//P      
interface Ipresenter<out V:IView<Ipresenter<V>>>{
//  @NotNull
//  IView getView();
  val view:V
}

abstract class BaseView<out P:BasePresenter<BaseView<P>>>:IView<P>{
  override val presenter:P

  init {
    presenter= findPresenterClass().newInstance()
    presenter.view=this
  }

  /**
   *       Class   
   */
  private fun findPresenterClass():Class<P>{
    //   ,             Class thisClass = this.getClass();
    var thisClass:Class<*> = this.javaClass
//    while(true) {
//      Type var10000 = thisClass.getGenericSuperclass();
//      if(!(var10000 instanceof ParameterizedType)) {
//        var10000 = null;
//      }
//      ParameterizedType var5 = (ParameterizedType)var10000;
//      if(var5 != null) {
//        Type[] var6 = var5.getActualTypeArguments();
//        if(var6 != null) {
//          var10000 = (Type)ArraysKt.firstOrNull((Object[])var6);
//          if(var10000 != null) {
//            Type var2 = var10000;
//            if(var2 == null) {
//              throw new TypeCastException("null cannot be cast to non-null type java.lang.Class<P>");
//            }
//
//            return (Class)var2;
//          }
//        }
//      }
//    }
    //             
    while (true){
      (thisClass.genericSuperclass as? ParameterizedType)
          ?.actualTypeArguments
          ?.firstOrNull()
          ?.let {
            return it as Class<P>
          }?.run{
              thisClass=thisClass.superclass ?:throw IllegalAccessException()
            }
          }
    }

  }


abstract class BasePresenter<out V:IView<BasePresenter<V>>>:Ipresenter<V>{
  //lateinit      
  //@UnsafeVariance                
  override lateinit var view:@UnsafeVariance V
}

class MainView:BaseView<MainPresenter>()

class MainPresenter:BasePresenter<MainView>()

class Mvp{
  init {
    MainView().presenter.let(::println)
    //        
//    BasePresenter var1 = (new MainView()).getPresenter();
//    System.out.println(var1);
    MainView().presenter.let { println("shiming P="+it) }
    //        
//    var1 = (new MainView()).getPresenter();
//    MainPresenter it = (MainPresenter)var1;
//    String var3 = "shiming P=" + it;
//    System.out.println(var3);
//    (new MainPresenter()).getView();

  }
}
출력 결 과 는:shiming P=com.kotlin.demo.star_demo.MainPresenter@fc35795총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기