📜 ⬆️ ⬇️

Security variables in Kotlin for example Java

Most recently, I had a conversation with a colleague about new programming languages. After talking about Kotlin, my friend dropped the phrase “There, zero cannot be transmitted if it does not indicate that the variable can be nullable”. This phrase greatly puzzled me - is it really that the killer Kotlin features are so important in comparison with the already known language capabilities of Java? Reflections on this question resulted in a whole range of examples in which I want to show (first of all to myself, probably) why all these new language possibilities are needed.

The most boring part of developing an already run-in language is routine tasks. For example, the display of pictures. Absolutely ordinary task, which in any project acquires a number of conventions. I will cite as an example several such:


Absolutely everyday conventions that are supported by many ready-made libraries (for example, for android it is Picasso, Glide, etc.).
')
Accordingly, for each download you need to transfer a set of similar settings. It is desirable that it eats less processor time and memory, it is possible to use templates, etc ...

In its most basic form, a set of such data will represent about the following class:

public class ImageSets { Boolean inCircle = false; Boolean needFit = false; Size size = null; int defaultDrawableResource = -1; } 

If you leave it like this, then working with it will look something like this:

Example
 void useCase() { BaseJavaClass some = new BaseJavaClass(); some.inCircle = true; some.needFit = true; some.defaultDrawableResource = 0; some.size = new Size(128, 128); System.out.println(some.inCircle); System.out.println(some.needFit); System.out.println(some.size); } static ImageSets pattern(){ BaseJavaClass some = new BaseJavaClass(); some.inCircle = true; some.needFit = true; some.defaultDrawableResource = 0; some.size = new Size(128, 128); return some; } 


This approach has several drawbacks, here are a couple of those that always cause me more irritation:


It is common to fight the first ailment with setters (you can of course declare a constructor with the entire set of variables, but if there are more than three of them in Java, plus some of them may not be necessary, we will definitely get calls like Some (0, 0, null, null, null, -1, 5)):

Lot of code
  public BaseJavaClass setInCircle(Boolean inCircle) { this.inCircle = inCircle; return this; } public BaseJavaClass setNeedFit(Boolean needFit) { this.needFit = needFit; return this; } public BaseJavaClass setSize(Size size) { this.size = size; return this; } public BaseJavaClass setDefaultDrawableResource(int defaultDrawableResource) { this.defaultDrawableResource = defaultDrawableResource; return this; } void useCase(){ BaseJavaClass some = new BaseJavaClass() .setInCircle(true) .setNeedFit(true) .setDefaultDrawableResource(0) .setSize(new Size(128, 128)); } static BaseJavaClass pattern1() { return new BaseJavaClass() .setInCircle(true) .setNeedFit(true) .setSize(new Size(128, 128)); } 


Well, let's say. But what to do with the second problem? Usually, to solve it, the _Bulder helper class is used, the call of which will contain the setters, and the call of the main class only getters:

A lot of code
 public class ImageSets { protected Boolean inCircle = false; protected Boolean needFit = false; protected Size size = null; protected int defaultDrawableResource = -1; public Boolean getInCircle() { return inCircle; } public Boolean getNeedFit() { return needFit; } public Size getSize() { return size; } public int getDefaultDrawableResource() { return defaultDrawableResource; } public static final ImageSets pattern = new ImageSetsBuilder() .setInCircle(true) .setNeedFit(true) .setDefaultDrawableResource(0) .setSize( new Size(128, 128)); } public class ImageSetsBuilder extends ImageSets { public ImageSetsBuilder setInCircle(Boolean inCircle) { this.inCircle = inCircle; return this; } public ImageSetsBuilder setNeedFit(Boolean needFit) { this.needFit = needFit; return this; } public ImageSetsBuilder setSize(Size size) { this.size = size; return this; } public ImageSetsBuilder setDefaultDrawableResource(int defaultDrawableResource) { this.defaultDrawableResource = defaultDrawableResource; return this; } } 


There are many other ways, I gave the most common ways to solve.
What happened to our data? How did it happen that a class containing only 4 variables has grown to such sizes? What happens when adding variables?
The same class, but in the Kotlin language will look like this:

 class ImageSets( val inCircle: Boolean = false, val needFit: Boolean = false, val size: Pair<Int, Int>? = null, val defaultDrawableResource: Int = -1) 

Everything! We can use:

 val pattern = ImageSets( inCircle = true, needFit = true, defaultDrawableResource = 0, size = 128 to 128) fun useCase(){ val some = ImageSets( inCircle = true, needFit = true, defaultDrawableResource = 0) print(some.needFit) } 

An example written in Kotlin gives us the following advantages:

Source: https://habr.com/ru/post/344864/


All Articles