401 is about failed Authentication - I say who I am, do you believe me? If not - respond with 401 Unauthenticated
Example: login failed due to invalid credentials.
403 is about failed Authorization - my authentication is accepted, can I access this? If not - respond with 403 Unauthorized
Example: access to specific resource is not permitted with my role.
pretty
Thursday, 14 July 2022
Wednesday, 24 February 2021
Kotlin contravariance samples
Contravariance is used to allow adding into collection values of type T and T subtypes.
The collection itself, however, is allowed to contain items of type T and any super types of T (because of this it is not safe to get from
this collection, with the exception of getting the root of type hierarchy Any?).
1. Use site variance
Sample: list with contravariance acts as a consumer.
It is safe to add into list the object of declared type B, or it's subtypes. It is not safe to retrieve object of type B from the list, because list of objects with super types of B may be provided. However, it is safe to retrieve the Kotlin most basic type Any? from the list.
Sample: contravariance in Comparator.
Compare list of Ints using Comparator<Number>.
The same sample without contravariance for Comparator is below. Without contravariance sortedWithWrapper() function could not return List<Int>, but only List<Number>. This happens because List<Int> is upcasted to List<Number>, to match the invariant T of the Comparator.
2. Declaration site variance
Declaration site variance is available in Kotlin, unlike Java where only use-site variance is possible.
Sample: Class with contravariance. Consumer cannot have contravariant type T in invariant or out positions.
Consumer class with contravariant T cannot accept another consumer with contravariant T.
This is due to AnotherConsumer can be extended by the class that cancels the contravariant 'in' modifier:
Allowing to accept another contravariant consumer would lead to ClassCastException.
As an example of the above, in this snippet AnotherConsumerC would be called with the wrong type A (omitting compiler variance checking with @UnsafeVariance annotation).
1. Use site variance
Sample: list with contravariance acts as a consumer.
It is safe to add into list the object of declared type B, or it's subtypes. It is not safe to retrieve object of type B from the list, because list of objects with super types of B may be provided. However, it is safe to retrieve the Kotlin most basic type Any? from the list.
open class A open class B : A() class C : B() // Can receive list of B or its super types (A, Any, Any? types in this sample). // Allows to put B or B subtypes into list (C in this sample). // Cannot get fom List - except, can only get most generic type Any? from list. fun listAsConsumer(list: MutableList<in B>) { // Type mismatch: inferred type is Any? but B was expected // val b: B = list[0] // Type mismatch: inferred type is A but B was expected // list.add(A()) // Cannot get fom List - except, can only get most generic type Any? from list. val any: Any? = list[0] // Allowed to add B or its subtypes into list list.add(B()) list.add(C()) } fun main() { listAsConsumer(mutableListOf<A>(A())) }
Sample: contravariance in Comparator.
Compare list of Ints using Comparator<Number>.
fun <T> Iterable<T>.sortedWithWrapper(comparator: Comparator<in T>): List<T> { return this.sortedWith(comparator) } fun main() { val comparator: Comparator<Number> = Comparator { o1: Number, o2: Number -> o1.toDouble().compareTo(o2.toDouble()) } val intList: List<Int> = listOf(4, 7) val result: List<Int> = intList.sortedWithWrapper(comparator) }
The same sample without contravariance for Comparator is below. Without contravariance sortedWithWrapper() function could not return List<Int>, but only List<Number>. This happens because List<Int> is upcasted to List<Number>, to match the invariant T of the Comparator.
fun <T> Iterable<T>.sortedWithWrapper(comparator: Comparator<T>): List<T> { return this.sortedWith(comparator) } fun main() { val comparator: Comparator<Number> = Comparator { o1: Number, o2: Number -> o1.toDouble().compareTo(o2.toDouble()) } val intList: List<Int> = listOf(4, 7) // Type mismatch: inferred type is List<Number> but List<Int> was expected // val result: List<Int> = intList.sortedWithWrapper(comparator) val result: List<Number> = intList.sortedWithWrapper(comparator) }
2. Declaration site variance
Declaration site variance is available in Kotlin, unlike Java where only use-site variance is possible.
Sample: Class with contravariance. Consumer cannot have contravariant type T in invariant or out positions.
open class A open class B : A() class C : B() class Consumer<in T> { // Type parameter T is declared as 'in' but occurs in 'invariant' // position in type T? // var x: T? = null fun consume(x: T) {} // Ok, List is defined as List<out T>, // so it is a producer for this Consumer class fun consume(x: List<T>) {} // Type parameter T is declared as 'in' but occurs in 'invariant' position // in type Array<T> // fun consume(x: Array<T>) {} // Type parameter T is declared as 'in' but occurs in 'out' position // in type T? // fun produce() : T? { return x } } fun main() { // Consumer of B (can be assigned Consumer of supertypes (A, Any, Any?)), // but now minimum B or its subtypes are accepted into consume() val consumerB: Consumer<B> = Consumer<A>() consumerB.consume(C()) // Type mismatch: inferred type is A but B was expected // consumerC.consume(A()) // Type mismatch: inferred type is Consumer<B> but Consumer<A> was expected // val consumerA: Consumer<A> = Consumer<B>() }
Consumer class with contravariant T cannot accept another consumer with contravariant T.
class AnotherConsumer<in T> { fun consume() {} } class Consumer<in T> { // Type parameter T is declared as 'in' but occurs in 'out' position // in type AnotherConsumer// fun consume(x: AnotherConsumer<T>) {} }
This is due to AnotherConsumer can be extended by the class that cancels the contravariant 'in' modifier:
open class AnotherConsumer<in T> { open fun consume(x: T) {} } class AnotherConsumerChild: AnotherConsumer<T>() { var x: T? = null override fun consume(x: T) { this.x = x } fun getT(): T? { return x } }
Allowing to accept another contravariant consumer would lead to ClassCastException.
As an example of the above, in this snippet AnotherConsumerC would be called with the wrong type A (omitting compiler variance checking with @UnsafeVariance annotation).
open class A open class B : A() class C : B() { fun c() {} } open class AnotherConsumer<in T> { open fun consume(x: T) {} } // Overrides contravariance in parent type class AnotherConsumerC: AnotherConsumer<C>() { override fun consume(x: C) { x.c() } } open class Consumer<in T> { open fun consume(anotherConsumer: AnotherConsumer<@UnsafeVariance T>) {} } open class ConsumerA: Consumer<A>() { override fun consume(anotherConsumer: AnotherConsumer<A>) { anotherConsumer.consume(A()) } } fun main() { val consumerA = ConsumerA() // Allowed because parent Consumer<in T> is contravariant val consumerC: Consumer<C> = consumerA // Produces Exception in thread "main" // java.lang.ClassCastException: A cannot be cast to C consumerC.consume(AnotherConsumerC()) }
Wednesday, 24 July 2019
Android ScrollView child width is larger than the screen (Api 21 bug)
On Android Lollipop this layout would produce a screen where children views of the ScrollView would have incorrect width.
And this the correct result, from api 27
To fix this ScrollView issue on api 21 devices, the child view "android:layout_margin" should be replaced with "android:padding". If it is not acceptable for the layout to have padding instead of margin (for example due to background color or click area placement) - padding can be set on parent container views. rows="20"
Subscribe to:
Posts
(
Atom
)