<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dmitry.log</title>
        <link>https://velog.io/</link>
        <description>Power Weekend</description>
        <lastBuildDate>Wed, 12 May 2021 11:57:30 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dmitry.log</title>
            <url>https://images.velog.io/images/dmitry-_-11/profile/9724a7b2-aff6-4319-b906-c40e3067879c/Dmitry-Klokov-barbell.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dmitry.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dmitry-_-11" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Android Testing - Test Doubles (Terminology)]]></title>
            <link>https://velog.io/@dmitry-_-11/Android-Testing-Test-Doubles-Terminology</link>
            <guid>https://velog.io/@dmitry-_-11/Android-Testing-Test-Doubles-Terminology</guid>
            <pubDate>Wed, 12 May 2021 11:57:30 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/dmitry-_-11/post/5ab93c47-d0a2-4b44-bd0a-a583fdf49f60/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Benefit All Lifters 03 : suspend keyword in DAO - @Query that returns LiveData<T>]]></title>
            <link>https://velog.io/@dmitry-_-11/Benefit-All-Lifters-03-suspend-keyword-in-DAO-Query-that-returns-LiveDataT</link>
            <guid>https://velog.io/@dmitry-_-11/Benefit-All-Lifters-03-suspend-keyword-in-DAO-Query-that-returns-LiveDataT</guid>
            <pubDate>Wed, 05 May 2021 13:03:24 GMT</pubDate>
            <description><![CDATA[<h2 id="case-01---suspend-keyword">Case 01 :  Suspend Keyword</h2>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/84432d7a-29c3-4557-98b3-43f84fbffb7e/carbon%20(1).png" alt=""></p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/f8ba8f48-fdaf-427a-9be7-97f88ba7f009/carbon%20(2).png" alt=""></p>
<blockquote>
<h3 id="coroutinesroomexecute">CoroutinesRoom.execute</h3>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/b8d57d35-db8d-4c2c-a1a3-5433ee3f6f7f/image.png" alt=""></p>
<h2 id="case-02--livedatat">Case 02 : LiveData&lt;T&gt;</h2>
<pre><code class="language-kotlin">@Query(&quot;SELECT * FROM user ORDER BY userId DESC&quot;)
fun getAllUsers(): LiveData&lt;List&lt;User&gt;&gt;</code></pre>
<pre><code class="language-java">// generated Database_Impl.java
@Override
public LiveData&lt;List&lt;User&gt;&gt; getAllUsers() {
    //...
    return __db.getInvalidationTracker().createLiveData(...)
}</code></pre>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/6a803a8f-fbcd-42c9-bf7b-218ce210f11b/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/a38991f7-0729-4799-91f3-f81c05e1a83c/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/1344659c-853d-4d9b-9e1b-ee7c02e27420/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Benefit All Lifters 01 : Api desugaring, Room @TypeConverter]]></title>
            <link>https://velog.io/@dmitry-_-11/Benefit-All-Lifters-01-Api-desugaring-Room-TypeConverter</link>
            <guid>https://velog.io/@dmitry-_-11/Benefit-All-Lifters-01-Api-desugaring-Room-TypeConverter</guid>
            <pubDate>Sat, 01 May 2021 11:04:53 GMT</pubDate>
            <description><![CDATA[<h1 id="1-cannot-figure-out-how-to-save-this-field-into-database">1. Cannot figure out how to save this field into database.</h1>
<hr>
<h2 id="problem">Problem</h2>
<pre><code class="language-kotlin">@Entity(tableName = &quot;routines&quot;)
data class Routine (
    // other fields ...
        @ColumnInfo(name = &quot;date&quot;)
        var date: LocalDate = LocalDate.now()
 )</code></pre>
<image src="https://images.velog.io/images/dmitry-_-11/post/9c02e0f5-e615-4c27-817f-0e79ae3a7274/image.png" />


<h2 id="why">...Why?</h2>
<h3 id="referencing-complex-data-using-room--android-developer"><a href="https://developer.android.com/training/data-storage/room/referencing-data"><strong>Referencing complex data using Room | Android Developer</strong></a></h3>
<blockquote>
<p>Room provides functionality for converting between primitive and boxed types <strong>but doesn&#39;t allow for object references between entities</strong>.</p>
</blockquote>
<h3 id="use-type-converters">Use type converters</h3>
<p>Sometimes, you need your app to store a custom data type in a single database column. You support custom types by providing type converters, which are methods that tell Room how to convert custom types to and from known types that Room can persist. You identify type converters by using the <a href="https://developer.android.com/reference/androidx/room/TypeConverters"><strong>@TypeConverter</strong></a> annotation.</p>
<h2 id="solution">Solution</h2>
<image src="https://images.velog.io/images/dmitry-_-11/post/92c095d8-e44a-4ea1-9661-073cc3a5b48c/image.png" />

<image src="https://images.velog.io/images/dmitry-_-11/post/1542c959-7d35-403f-99d5-3212e1a38430/image.png" />

<h2 id="test">Test</h2>
<image src="https://images.velog.io/images/dmitry-_-11/post/463c74e1-cb11-4807-8718-8f7a54d5d2da/image.png" />


<h1 id="2-add-requiresapio-annotation">2. Add @RequiresApi(O) Annotation...?</h1>
<hr>
<h2 id="problem-1">Problem</h2>
<image src="https://images.velog.io/images/dmitry-_-11/post/a646905f-f914-4f82-9086-53deddfefa46/image.png" />



<h2 id="why-1">...Why?</h2>
<image src="https://images.velog.io/images/dmitry-_-11/post/fad4a7c7-05d8-4e78-9daa-243362dbfa71/image.png" />

<image src="https://images.velog.io/images/dmitry-_-11/post/9a24453a-4445-4210-9a96-d06466704b79/image.png" />

<h3 id="use-java-8-language-features-and-apis--android-developer"><a href="https://developer.android.com/studio/write/java8-support.html#library-desugaring">Use Java 8 language features and APIs | Android developer</a></h3>
<blockquote>
<p>If you&#39;re building your app using Android Gradle plugin 4.0.0 or higher, <strong>the plugin extends support for using a number of Java 8 language APIs without requiring a minimum API level for your app.</strong></p>
</blockquote>
<p>This additional support for older platform versions is possible because plugin 4.0.0 and higher extend the desugaring engine to also desugar Java language APIs. So, you can include standard language APIs that were available only in recent Android releases (such as <strong><code>java.util.streams</code></strong>) in apps that support older versions of Android.</p>
<h2 id="solution-1">Solution</h2>
<image src="https://images.velog.io/images/dmitry-_-11/post/796dd4a8-39ad-44be-9e39-9cf9dcd8a3af/image.png" />

<h2 id="result">Result</h2>
<image src="https://images.velog.io/images/dmitry-_-11/post/bc5a27a7-e8c4-4993-b77a-b23ac1ab1756/image.png" />



]]></description>
        </item>
        <item>
            <title><![CDATA[Jetpack Navigation 02]]></title>
            <link>https://velog.io/@dmitry-_-11/Jetpack-Navigation-02</link>
            <guid>https://velog.io/@dmitry-_-11/Jetpack-Navigation-02</guid>
            <pubDate>Wed, 17 Mar 2021 09:35:23 GMT</pubDate>
            <description><![CDATA[<h2 id="prev--jetpack-navigation-01"><a href="https://velog.io/@dmitry-_-11/Jetpack-Navigation-01">Prev | Jetpack Navigation 01</a></h2>
<h2 id="1-navigating-using-menus-drawers-and-bottom-navigation">1. Navigating using menus, drawers and bottom navigation</h2>
<hr>
<h3 id="navigationui-and-navigation-ui-ktx">NavigationUI and navigation-ui-ktx</h3>
<p>The Navigation Components include a <a href="http://d.android.com/reference/androidx/navigation/ui/NavigationUI">NavigationUI</a> class and <a href="https://developer.android.com/reference/kotlin/androidx/navigation/ui/package-summary#extension-functions-summary">navigation-us-ktx</a> kotlin extensions. <strong><code>NavigationUI</code></strong> has static methods that associate menu items with navigation destinations, and <strong><code>navigation-ui-ktx</code></strong> is a set of extenstion functions that do the same. If <strong><code>NavigationUI</code></strong> finds a menu item with the same ID as a destination on the current graph, it configures the menu item to navigate to that destination.</p>
<h3 id="using-navigationui-with-an-options-menu">Using NavigationUI with an Options menu</h3>
<p>One of the easiest ways to use NavigationUI is to have it simplify option menu setup. In particular, NavigationUI simplifies handling the <strong><code>onOptionsItemSelected</code></strong> callback.</p>
<ol>
<li><p>Open <a href="https://github.com/googlecodelabs/android-navigation/blob/master/app/src/main/java/com/example/android/codelabs/navigation/MainActivity.kt">MainActivity.kt</a>
Notice how you already have the code for inflating the menu <strong><code>overflow_menu</code></strong> in <strong><code>onCreateOptionsMenu</code></strong></p>
<blockquote>
<h4 id="mainactivitykt">MainActivity.kt</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/058cca63-a79d-4c08-bc05-d22bb56d29b3/image.png" alt=""></p>
</li>
<li><p>Open <strong><code>res/menu/overflow_menu.xml</code></strong></p>
</li>
<li><p>Update your overflow menu to include the <strong><code>settings_dest</code></strong></p>
<blockquote>
<h4 id="overflow_menuxml">overflow_menu.xml</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/65b26fd2-49de-4cfc-9cdb-f194da3ee757/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/c76babc6-1c31-4003-b43e-2515f0a3df6a/image.png" alt=""></p>
</li>
<li><p>Open <strong><code>MainActivity.kt</code></strong></p>
</li>
<li><p>Have NavigationUI handle <strong><code>onOptionsItemSelected</code></strong> with the <a href="">onNavDestinationSelected</a> helper method. If the menu item is not meant to navigate, handle with <strong><code>super.onOptionsItemSelected</code></strong></p>
<blockquote>
<h4 id="mainactivitykt-1">MainActivity.kt</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/ec9e011b-9b53-4463-a919-f1fc9eb263f9/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/5de02604-34f9-49cf-8967-e300cb6f9504/image.png" alt=""></p>
</li>
<li><p>Run your app. You should have a functional ActionBar menu that navigates to the SettingsFragment.</p>
</li>
</ol>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/8bd19167-fcc8-4f49-a8e1-a6aad65c8c0b/Screenshot_1615975333.png" alt=""></p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/b6ca82d5-e53e-4f03-b698-0f3c132faa94/Screenshot_1615975336.png" alt=""></p>
<h3 id="using-navigationui-to-configure-bottom-navigation">Using NavigationUI to configure Bottom Navigation</h3>
<p>The coded already contains the XML layout code for implementing bottom navigation, which is why you see the bottom navigation bar. But it doesn&#39;t navigate anywhere.</p>
<ol>
<li><p>Open <strong><code>res/layout/navigation_activity.xml (h470dp)</code></strong> and click the <strong>Text</strong> tab
Notice how the XML layout code for bottom navigation is there and refers to <strong><code>bottom_nav_menu.xml</code></strong></p>
<blockquote>
<h4 id="navigation_activityxml-h470dp">navigation_activity.xml (h470dp)</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/3567bff1-7a82-42b5-97da-ab060a359e0e/image.png" alt=""></p>
</li>
<li><p>Open <strong><code>res/menu/bottom_nav_menu.xml</code></strong>
Notice how there are two items for bottom navigation and that <strong>their ids match</strong> the destinations of navigation graph destinations:</p>
<blockquote>
<h4 id="bottom_nav_menuxml">bottom_nav_menu.xml</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/41d81778-6d2a-4dc4-b2c6-e8e29b607920/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>Let&#39;s make the bottom navigation actually do something using NavigationUI.</p>
</li>
<li><p>Open <strong><code>MainActivity.kt</code></strong></p>
</li>
<li><p>Implement the <strong><code>setupBottomNavMenu</code></strong> method using <strong><a href="https://developer.android.com/reference/kotlin/androidx/navigation/ui/NavigationUI#setupwithnavcontroller_2">setupWithNavController(bottomNavigationView: BottomNavigationView, navController: NavController)</a></strong></p>
<blockquote>
<h4 id="mainactivitykt-2">MainActivity.kt</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/56d60eb3-723e-423e-9efe-6022987ba3ae/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/69e32704-daa5-4637-ba06-f302c644d6e5/image.png" alt=""></p>
</li>
</ol>
<p>Now your bottom navigation works!</p>
<h3 id="using-navigationui-to-configure-a-navigation-drawer">Using NavigationUI to configure a Navigation Drawer</h3>
<p>Finally, let&#39;s use <strong><code>NavigationUI</code></strong> to configure the side navigation and navigation drawer, including handling the ActionBar and <strong><a href="https://developer.android.com/topic/libraries/architecture/navigation/navigation-principles#the_up_button_never_exits_your_app">proper up navigation</a></strong>. You&#39;ll see this if you&#39;ve got a large enough screen or if the screen&#39;s too short for bottom navigation.</p>
<p>First observe how the proper layout XML code is already in the app.</p>
<ol>
<li><p>Open both <strong><code>navigation_activity.xml</code></strong> and <strong><code>navigation_activity.xml (w960dp)</code></strong></p>
<p>Notice how both layouts contain a <a href="https://material.io/develop/android/components/navigation-view/">NavigationView</a> connected to nav_drawer_menu. In the tablet version (w960dp) the NavigationView is always on screen. On smaller devices the NavigationView is <a href="https://developer.android.com/training/implementing-navigation/nav-drawer">nested within a DrawerLayout</a>.</p>
<blockquote>
<h4 id="navigation_activityxml">navigation_activity.xml</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/f1fb7a67-5fb0-4762-8b9c-fd1b6d1d9517/image.png" alt=""></p>
<blockquote>
<h4 id="navigation_activityxml-w960dp">navigation_activity.xml (w960dp)</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/da900cbc-c23f-4f6a-a44c-da48953c5642/image.png" alt=""></p>
<p>Now to start implementing the NavigationView navigation.</p>
</li>
<li><p>Open <strong><code>MainActivity.kt</code></strong></p>
</li>
<li><p>Implement the <strong><code>setupNavigationMenu</code></strong> method using <strong><a href="">setupWithNavController(navigationView: NavigationView, navController: NavController)</a></strong>. Notice how this version of the method takes a <strong><code>NavigationView</code></strong> and not a <strong><code>BottomNavigationView</code></strong>.</p>
<blockquote>
<h4 id="mainactivitykt-3">MainActivity.kt</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/6d69b50f-bbca-4965-b03f-958c711d6793/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/e8164c05-b61e-4509-8b5f-01caf27daf37/image.png" alt=""></p>
<p>Now the navigation view menu will show on the screen, but it will not affect the ActionBar.</p>
<p>Setting up the <strong><code>ActionBar</code></strong> requires creating an instance of <strong><a href="https://developer.android.com/reference/androidx/navigation/ui/AppBarConfiguration">AppBarConfiguration</a></strong>. The purpose of <strong><code>AppBarConfiguration</code></strong> is to specify the configuration options you want for your toolbars, <a href="https://medium.com/@ankitashettya/collapsing-toolbar-in-android-using-androidx-jetpack-d54678ac4cbc">collapsing toolbars</a>, and action bars. Configuration options include whether the bar must handle a drawer layout and which destinations are considered <strong>top-level destinations</strong>.</p>
<p>Top-level destinations are the root-level destinations of your app. These destinations do not display an &quot;up&quot; button in the app bar, and they display the drawer icon if the destination uses a drawer layout.</p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/6f633a86-26ac-4099-ad20-e9f160bc6cff/image.png" alt=""></p>
</li>
</ol>
<ol start="4">
<li><p>Create an <strong><code>AppBarConfiguration</code></strong> by passing in a set of top-level destination IDs and the drawer layout.</p>
<blockquote>
<h4 id="mainactivitykt-4">MainActivity.kt</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/1854de77-4de3-4fc7-866f-b5a8bf131715/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/bc8586f1-0f15-4581-b2ec-7356c7415d37/image.png" alt=""></p>
<blockquote>
<p><strong>How to determine top-level destinations</strong></p>
</blockquote>
<p>Destinations reachable via global navigation UI, such as bottom nav or side nav, all appear to users as on the same top level of the hierarchy. Therefore, they are top level destinations. <strong>home_dest</strong> and <strong>deeplink_dest</strong> are in the bottom nav and we want the drawer icon to show on both of these destinations, so they are top-level destinations.</p>
<blockquote>
<p>Note that the start destination is always considered a top-level destination. If you don&#39;t specify a list of top-level destinations, then the only top-level destination is your start destination. You can learn more about <strong><a href="https://developer.android.com/topic/libraries/architecture/navigation/navigation-ui#appbarconfiguration">AppBarConfiguration</a></strong> in the documentation.</p>
</blockquote>
<p>Now that you have an AppBarConfiguration, you can call <strong><a href="https://developer.android.com/reference/kotlin/androidx/navigation/ui/NavigationUI#setupactionbarwithnavcontroller_1">NavigationUI.setupActionBarWithNavController</a></strong>. This will do the following:</p>
<ul>
<li><p>Show a title in the ActionBar based off of the destination&#39;s label</p>
</li>
<li><p>Display the Up button whenever you&#39;re <strong>not</strong> on a top-level destination</p>
</li>
<li><p>Display a drawer icon (hamburger icon) when you&#39;re on a top-level destination</p>
</li>
</ul>
</li>
<li><p>Implement <strong><code>setupActionBarWithNavController</code></strong></p>
<blockquote>
<h4 id="mainactivitykt-5">MainActivity.kt</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/97c2b761-7dbf-4f67-b0f4-47dec614f26a/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/398e3860-dfc6-4ed3-a6a9-6c8e2059e91a/image.png" alt=""></p>
<p>You should also have NavigationUI handle what happens when the Up button is pressed.</p>
</li>
</ol>
<ol start="6">
<li>Override <strong><code>onSupportNavigateUp</code></strong> and call <strong><a href="">NavigationUI.navigateUp</a></strong>, using the same <strong><code>AppBarConfiguration</code></strong>.<blockquote>
<h4 id="mainactivitykt-6">MainActivity.kt</h4>
</blockquote>
<img src="https://images.velog.io/images/dmitry-_-11/post/38711b1e-51f5-4647-9e3b-bbcbe2fdd8c2/image.png" alt=""><blockquote>
</blockquote>
<img src="https://images.velog.io/images/dmitry-_-11/post/f8991ea6-7ec5-4107-b7d4-53a4b6593b61/image.png" alt=""></li>
</ol>
<ol start="7">
<li><p>Run your code. If you open the app in split screen, you should have a working navigation drawer. The up icon and the drawer icon should display at the appropriate times and work correctly.</p>
<blockquote>
<p><strong>Notice</strong></p>
</blockquote>
<p>The layout <strong>navigation_activity.xml (h470dp)</strong> will be used on phones in portrait mode. This layout does not include the navigation drawer and instead includes the bottom navigation, which is why you should open the app in split screen to see the navigation drawer. The reason there is <strong>not</strong> a layout with both a navigation drawer and bottom navigation is because Material Design guidelines <a href="https://material.io/design/components/navigation-drawer.html#usage">cautions against this</a>.</p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/b8b2925d-57de-44cd-baa8-fc4f51f8b6b4/aa078f00b9501f7e.gif" alt=""></p>
<p>Adding new destinations to a <strong><code>NavigationView</code></strong> is easy. Once you have the navigation drawer working with up and back navigation, you just need to add the new menu item.</p>
</li>
<li><p>Open <strong><code>menu/nav_drawer_menu.xml</code></strong></p>
</li>
<li><p>Add a new menu item for <strong><code>setting_dest</code></strong></p>
<blockquote>
<h4 id="nav_drawer_menuxml">nav_drawer_menu.xml</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/5009947a-6d73-4a5d-9956-83e724a89aac/image.png" alt=""></p>
<p>Now your navigation drawers shows the Settings screen as a destination.</p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/3ecc951b-cc1c-4f66-b787-80d3489bce96/image.png" alt=""></p>
</li>
</ol>
<h2 id="2-deep-linking-to-a-destination">2. Deep Linking to a destination</h2>
<hr>
<h3 id="deep-links-and-navigation">Deep Links and Navigation</h3>
<p>Navigation components also include deep link support. <a href="https://developer.android.com/training/app-links/deep-linking">Deep links</a> are a way to jump into the middle of your app&#39;s navigation, whether that&#39;s from an actual URL link or a pending intent from a notification.</p>
<p>One benefit of using the navigation library to handle deep links is that it ensures users start on the right destination with the appropriate back stack from other entry points such as app widgets, notifications, or web links (covered in the next step).</p>
<p>Navigation provides a <strong><code>NavDeepLinkBuilder</code></strong> class to construct a <strong><code>PendingIntent</code></strong> that will take the user to a specific destination.</p>
<h3 id="add-a-deep-link">Add a Deep Link</h3>
<p>We&#39;ll use the <strong><code>NavDeepLinkBuilder</code></strong> to hook up an app widget to a destination.</p>
<ol>
<li><p>Open <strong><a href="https://github.com/googlecodelabs/android-navigation/blob/master/app/src/main/java/com/example/android/codelabs/navigation/DeepLinkAppWidgetProvider.kt">DeepLinkAppWidgetProvider.kt</a></strong></p>
</li>
<li><p>Add a <strong><code>PendingIntent</code></strong> constructed with <strong><code>NavDeepLinkBuilder</code></strong>:</p>
<blockquote>
<h4 id="deeplinkappwidgetproviderkt">DeepLinkAppWidgetProvider.kt</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/91c058c8-89a9-4068-988b-e7bd09efc9b1/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/e61c4773-20a9-442e-9ff6-920e61af6e85/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/abdad4aa-1634-401d-bbee-c1bc665e2b4a/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/9092d1a8-5c90-4a5b-8663-acfefc6ed53f/image.png" alt=""></p>
<p>Notice:</p>
<ul>
<li><strong><code>setGraph</code></strong> includes the navigation graph.</li>
<li><strong><code>setDestination</code></strong> specifies where the link goes to.</li>
<li><strong><code>setArguments</code></strong> includes any arguments you want to pass into your deep link.</li>
</ul>
<blockquote>
<p>By default <strong>NavDeepLinkBuilder</strong> will start your launcher Activity. You can override this behavior by passing in an activity as the context or set an explicit activity class via <strong>setComponentName()</strong>.</p>
</blockquote>
</li>
<li><p>Add the Deep Link widget to your home screen.
<img src="https://images.velog.io/images/dmitry-_-11/post/7811ff2c-acc3-443e-b7e8-77e468e6c7cf/image.png" alt=""></p>
</li>
</ol>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/0e375040-42fd-4ba0-b404-b3fc54b2731c/image.png" alt=""></p>
<ol start="4">
<li>Tap the widget, and verify that the Android destination opens with the correct argument. It should say &quot;From Widget&quot; at the top since that is the argument you passed in DeepLinkAppWidgetProvider.</li>
</ol>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/4ce8992a-aa13-4fff-a62a-1644a352327d/image.png" alt=""></p>
<ol start="5">
<li>Verify that hitting the back button takes you to the <strong><code>home_dest</code></strong> destination.</li>
</ol>
<blockquote>
<p>As a convenience, you can also call <strong>NavController</strong>&#39;s <strong>createDeepLink()</strong> method to use the <strong>Context</strong> and current navigation graph from the <strong>NavController</strong>.</p>
</blockquote>
<h3 id="deeplink-backstack">DeepLink Backstack</h3>
<p>The backstack for a deep link is determined using the navigation graph you pass in. If the explicit Activity you&#39;ve chosen has a <a href="https://developer.android.com/training/appbar/up-action.html#declare-parent">parent activity</a>, those parent Activities are also included.</p>
<p>The backstack is generated using the destinations specified with <strong><code>app:startDestination</code></strong>. In this app we only have one activity and one level of navigation, so the backstack will take you to the <strong><code>home_dest</code></strong> destination.</p>
<p>More complicated navigation can include nested navigation graphs. The <strong><code>app:startDestination</code></strong> at each level of the nested graphs determines the backstack. For more information on deep links and nested graphs, check out the <a href="http://d.android.com/topic/libraries/architecture/navigation/navigation-principles">Principles of Navigation</a>.</p>
<h2 id="3-associating-a-web-link-with-a-destination">3. Associating a web link with a destination</h2>
<hr>
<h3 id="the-deeplink-element">The &lt;deepLink&gt; element</h3>
<p>One of the most common uses of a deep link is to allow a web link to open an activity in your app. Traditionally you would use an <a href="https://developer.android.com/training/app-links/deep-linking#adding-filters">intent-filter and associate a URL with the activity</a> you want to open.</p>
<p>The navigation library makes this extremely simple and allows you to map URLs directly to destinations in your navigation graph.</p>
<p><strong><code>&lt;deepLink&gt;</code></strong> is an element you can add to a destination in your graph. Each <strong><code>&lt;deepLink&gt;</code></strong> element has a single required attribute: <strong><code>app:uri</code></strong>.</p>
<p>In addition to a direct URI match, the following features are supported:</p>
<ul>
<li><p>URIs without a scheme are assumed to be http and https. For example, <strong><code>www.example.com</code></strong> will match <strong><code>http://www.example.com</code></strong> and <strong><code>https://www.example.com</code></strong>.</p>
</li>
<li><p>You can use placeholders in the form of <strong><code>{placeholder_name}</code></strong> to match one or more characters. The String value of the placeholder is available in the arguments Bundle which has a key of the same name. For example, <strong><code>http://www.example.com/users/{id}</code></strong> will match <strong><code>http://www.example.com/users/4</code></strong>.</p>
</li>
<li><p>You can use the <strong><code>.*</code></strong> wildcard to match zero or more characters.</p>
</li>
<li><p>NavController will automatically handle <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_VIEW">ACTION_VIEW</a> intents and look for matching deep links.</p>
</li>
</ul>
<h3 id="add-a-uribased-deep-link-using-deeplink">Add a URIbased Deep Link using &lt;deepLink&gt;</h3>
<p>In this step, you&#39;ll add a deep link to <a href="http://www.example.com/">www.example.com</a></p>
<ol>
<li><p>Open <strong><code>mobile_navigation.xml</code></strong></p>
</li>
<li><p>Add a <strong><code>&lt;deepLink&gt;</code></strong> element to the <strong><code>deeplink_dest</code></strong> destination.</p>
<blockquote>
<h4 id="mobile_navigationxml">mobile_navigation.xml</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/f72dce02-f50f-4b4e-9a31-09d0b29a9639/image.png" alt=""></p>
</li>
<li><p>Open <strong><code>AndroidManifest.xml</code></strong></p>
</li>
<li><p>Add the <strong><code>nav-graph</code></strong> tag. This will ensure the appropriate intent filter is generated</p>
<blockquote>
<h4 id="androidmanifestxml">AndroidManifest.xml</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/283dd265-0d86-4f45-8a43-a2180015b8f4/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/c87694b9-77fe-4f6d-8923-94666d29da3a/image.png" alt=""></p>
</li>
<li><p>Launch your app using a deep link. There are two ways to do this:</p>
<ul>
<li><p>Use <strong><code>adb</code></strong> :
<img src="https://images.velog.io/images/dmitry-_-11/post/f8e64266-ddd3-43dc-beaa-f140f6d07184/image.png" alt=""></p>
</li>
<li><p>Navigate via the Google app. You should be able to put <a href="http://www.example.com/urlTest">www.example.com/urlTest</a> in the search bar and the disambiguation window will appear. Select Navigation codelab
<img src="https://images.velog.io/images/dmitry-_-11/post/6165def8-91e8-4164-a222-f181a9bdf4cc/image.png" alt=""></p>
<p>Either way, you should see the message &quot;urlTest&quot; on screen. This was passed through to the fragment, from the URL.</p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/d0b98d0d-2603-429f-b705-c9feb291411b/image.png" alt=""></p>
</li>
</ul>
</li>
</ol>
<h2 id="learn-more--google-codelabs"><a href="https://developer.android.com/codelabs/android-navigation?index=..%2F..%2Findex#12">Learn more | Google Codelabs</a></h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[Jetpack Navigation 01]]></title>
            <link>https://velog.io/@dmitry-_-11/Jetpack-Navigation-01</link>
            <guid>https://velog.io/@dmitry-_-11/Jetpack-Navigation-01</guid>
            <pubDate>Tue, 16 Mar 2021 12:52:35 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>Reference</strong>
<a href="https://developer.android.com/guide/navigation">Android Navigation | Android developers</a>
<a href="https://developer.android.com/codelabs/android-navigation#0">Jetpack Navigation | Google Codelabs</a></p>
</blockquote>
<h2 id="1-overview-of-navigation">1. Overview of Navigation</h2>
<hr>
<p>The Navigation Component consists of <strong>three key parts</strong>, working together. They are:</p>
<ol>
<li><p><strong>Navigation Graph</strong> (New XML resource) - This is a resource that contains all navigation-related information in one centralized location. This includes all the places in your app, known as <em>destinations</em>, and possible paths a user could take through your app.</p>
</li>
<li><p><strong>NavHostFragment</strong> (Layout XML view) - This is a special widget you add to your layout. It displays different destinations from your <strong>Navigation Graph</strong>.</p>
</li>
<li><p><strong>NavController</strong> (Kotlin/Java object) - Ths is an object that keeps track of the current position within the navigation graph. It orchestrates swapping destination content in the <strong><code>NavHostFragment</code></strong> as you move through a navigation graph.</p>
</li>
</ol>
<p>When you navigate, you&#39;ll use the NavController object, telling it where you want to go or what path you want to take in your Navigation Graph. The NavController will then show the appropriate destination in the <strong><code>NavHostFragment</code></strong>.</p>
<h2 id="2-introducing-the-navigation-graph">2. Introducing the Navigation Graph</h2>
<hr>
<h3 id="destinations">Destinations</h3>
<p>The Navigation Component introduces the concept of a <em>destination</em>. A destination is any place you can navigate to in your app, usually a fragment or an activity. These are supported out of the box, but you can also <a href="http://d.android.com/arch/navigation/navigation-add-new">make your own custom destination types</a> if needed.</p>
<h3 id="navigation-graph">Navigation Graph</h3>
<p>A <em>navigation graph</em> is a new resource type that defines all the possible paths a user can take through an app. It shows visually all the destinations that can be reached from a given destination. Android Studio displays the graph in its Navigation Editor. Here&#39;s part of the starting navigation graph you&#39;ll create for your app:
<img src="https://images.velog.io/images/dmitry-_-11/post/ca0ebf94-2844-4c44-adf9-0c43f7b1f6c1/image.png" alt=""></p>
<h3 id="exploring-the-navigation-editor">Exploring the Navigation Editor</h3>
<ol>
<li><p>Open <a href="https://github.com/googlecodelabs/android-navigation/blob/master/app/src/main/res/navigation/mobile_navigation.xml"><strong>res/navigation/mobile_navigation.xml</strong></a></p>
</li>
<li><p>Click <strong>Design</strong> to go into Design mode <img src="https://images.velog.io/images/dmitry-_-11/post/05b66420-6f9a-4777-bfa5-7413fdde0c23/image.png" alt="">The navigation graph shows the available destinations. The arrows between the destinations are called <em>actions</em>. You&#39;ll learn more about actions later.</p>
</li>
<li><p>Click on a destination to see its attributes. <img src="https://images.velog.io/images/dmitry-_-11/post/fa9ea40f-d769-4101-ac6c-55ef5d3b62ea/image.png" alt=""></p>
</li>
<li><p>Click on any action, represented by an arrow, to see its attributes. <img src="https://images.velog.io/images/dmitry-_-11/post/f62cc020-f010-4c66-8aa0-d741005d2cdd/image.png" alt=""></p>
</li>
</ol>
<h3 id="anatomy-of-a-navigation-xml-file">Anatomy of a navigation XML file</h3>
<p>All of the changes you make in the graphical Navigation Editor change the underlying XML file, similar to the way the Layout Editor modifies the layout XML.</p>
<p>Click the <strong>Text</strong> tab and you&#39;ll see some <a href="https://github.com/googlecodelabs/android-navigation/blob/master/app/src/main/res/navigation/mobile_navigation.xml">XML like this</a>:
<img src="https://images.velog.io/images/dmitry-_-11/post/c2cdf576-511d-401b-9298-41685d73fc25/image.png" alt=""></p>
<p>Notice:</p>
<ul>
<li><p><strong><code>&lt;navigation&gt;</code></strong> is the root node of every navigation graph.</p>
</li>
<li><p><strong><code>&lt;navigation&gt;</code></strong> contains one or more destinations, represented by <strong><code>&lt;activity&gt;</code></strong> or <strong><code>&lt;fragment&gt;</code></strong> elements.</p>
</li>
<li><p><strong><code>app:startDestination</code></strong> is an attribute that specifies the destination that is launched by default when the user first opens the app.</p>
</li>
</ul>
<p>Let&#39;s take a look at fragment destination:
<img src="https://images.velog.io/images/dmitry-_-11/post/d9b745dc-349d-4cf7-8fa9-6ad4cbd2bf6b/image.png" alt=""></p>
<p>Notice:</p>
<ul>
<li><p><strong><code>android:id</code></strong> defines an ID for the fragment that you can use to reference the destination elsewhere in this XML and your code.</p>
</li>
<li><p><strong><code>android:name</code></strong> declares the fully qualified class name of the fragment to instantiate when you navigate to that destination.</p>
</li>
<li><p><strong><code>tools:layout</code></strong> specifies what layout should be shown in the graphical editor.</p>
</li>
</ul>
<p>Some <strong><code>&lt;fragment&gt;</code></strong> tags also contain <strong><code>&lt;action&gt;</code></strong>, <strong><code>&lt;argument&gt;</code></strong> and <strong><code>&lt;deepLink&gt;</code></strong>, all of which we&#39;ll cover later.</p>
<h2 id="3-add-a-destination-to-the-navigation-graph">3. Add a Destination to the Navigation Graph</h2>
<hr>
<p>You must add a destination to the navigation graph before you can navigate to it.</p>
<ol>
<li><p>Open <strong><code>res/navigation/mobile_navigation.xml</code></strong>, and click the <strong>Design</strong> tab.</p>
</li>
<li><p>Click the <strong>New Destination</strong> icon, and select <strong><code>settings_fragment</code></strong></p>
</li>
</ol>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/1e2f2f0a-0650-4e26-8a74-cb388b956c97/image.png" alt=""> The result is a new destination, which renders a preview of the fragment&#39;s layout in the design view.
<img src="https://images.velog.io/images/dmitry-_-11/post/f2c3a2c3-41cb-43bf-a9fe-67760c4f73de/image.png" alt=""></p>
<blockquote>
<p><strong>Note</strong> : You can also edit the XML file directly to add destinations:
<img src="https://images.velog.io/images/dmitry-_-11/post/3aff63e2-6fbb-47e8-a498-4df0ddb93ca7/image.png" alt=""> To follow our naming convention, change the id to <strong>settings_dest</strong> from the default <strong>settingsFragment</strong>.</p>
</blockquote>
<h2 id="4-using-the-navigation-graph-to-navigate">4. Using the Navigation Graph to Navigate</h2>
<hr>
<h3 id="activities-and-navigation">Activities and Navigation</h3>
<p>The Navigation component follows the guidance outlined in the <a href="http://d.android.com/topic/libraries/architecture/navigation/navigation-principles">Principles of Navigation</a>. The Principles of Navigation recommend you use activities as entry points for your app. Activities will also contain global navigation, such as the bottom nav,</p>
<p>In comparison, fragments will be the actual destination-specific layouts.</p>
<p>To get this all to work, you need to modify your activity layouts to contain a special widget called a <strong><a href="http://d.android.com/reference/androidx/navigation/fragment/NavHostFragment">NavHostFragment</a></strong>. A <strong><code>NavHostFragment</code></strong> swaps different fragment destinations in and out as you navigate through the navigation graph.
<img src="https://images.velog.io/images/dmitry-_-11/post/14d6b8e5-e00c-4d7c-a94b-7240b359ccac/image.png" alt=""></p>
<p>A simple layout supporting navigation similar to the picture above looks like this. An example of this code can be found in <a href="https://github.com/googlecodelabs/android-navigation/blob/master/app/src/main/res/layout-h470dp/navigation_activity.xml"><strong>res/layout-470dp/navigation_activity.xml</strong></a>:
<img src="https://images.velog.io/images/dmitry-_-11/post/38223bdf-e578-4816-ac5c-8e4a71c111fe/image.png" alt=""></p>
<p>Notice:</p>
<ul>
<li><p>This is a layout for an activity. It contains the global navigation, including a bottom nav and a toolbar.</p>
</li>
<li><p><strong><code>android:name=&quot;androidx.navigation.fragment.NavHostFragmnet&quot;</code></strong> and <strong><code>app:defaultNavHost=&quot;true&quot;</code></strong> connect the system back button to the <strong><code>NavHostFragment</code></strong></p>
</li>
<li><p><strong><code>app:navGraph=&quot;@navigation/mobile_navigation&quot;</code></strong> associates the <strong><code>NavHostFragment</code></strong> with a navigation graph. This navigation graph specifies all the destinations the user can navigate to, in this <strong><code>NavHostFragment</code></strong>.</p>
</li>
</ul>
<h3 id="navcontroller">NavController</h3>
<p>Finally, when a user does something like clicking a button, you need to trigger a navigate command. A special class called the <a href="https://developer.android.com/reference/androidx/navigation/NavController"><strong>NavController</strong></a> is what triggers the fragment swaps in the <strong><code>NavHostFragment</code></strong>.</p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/984a6bf8-af45-4f4e-96ef-9c1eb73922d8/image.png" alt=""></p>
<p>Note that you pass in either a destination or action ID to navigate. These are the IDs defined in the navigation graph XML. This is an example of passing in a destination ID.</p>
<p><strong><code>NavController</code></strong> is powerful because when you call methods like <strong><code>navigate()</code></strong> or <strong><code>popBackStack()</code></strong>, it translates these commands into the appropriate framework operations based on the type of destination you are navigating to or from. For example, when you call <strong><code>navigate()</code></strong> with an activity destination, the <strong><code>NavController</code></strong> calls <strong><code>startActivity()</code></strong> on your behalf.</p>
<p>There are a few ways to get a <strong><code>NavController</code></strong> object associated with your <strong><code>NavHostFragment</code></strong>. In Kotlin, it&#39;s recommended you use one of the following extension functions, depending on whether you&#39;re calling the navigation command from within a fragment, activity or view:</p>
<ul>
<li><p><a href="https://developer.android.com/reference/kotlin/androidx/navigation/fragment/package-summary#findnavcontroller"><strong>Fragment.findNavController()</strong></a></p>
</li>
<li><p><a href="https://developer.android.com/reference/kotlin/androidx/navigation/package-summary#%28android.view.View%29.findNavController%28%29"><strong>View.findNavController()</strong></a></p>
</li>
<li><p><a href="https://developer.android.com/reference/kotlin/androidx/navigation/package-summary#findnavcontroller"><strong>Activity.findNavController()</strong></a></p>
</li>
</ul>
<blockquote>
<p>Your <strong>NavController</strong> is associated with a <strong>NavHostFragment</strong>. Thus whichever method you use, you must be sure that the fragment, view, or view ID is either a <strong>NavHostFragment</strong> itself, or has a <strong>NavHostFragment</strong> as a parent. Otherwise you will get an <strong>IllegalStateException</strong>.</p>
</blockquote>
<h3 id="navigate-to-a-destination-with-navcontroller">Navigate to a Destination with NavController</h3>
<p>It&#39;s your turn to navigate using <a href="">NavController</a>. You&#39;ll hook up the <strong>Navigate To Destination</strong> button to the <strong><code>flow_step_one_dest</code></strong> destination (which is a destination that is a <strong><code>FlowStepFragment</code></strong>:</p>
<ol>
<li><p>Open <a href="https://github.com/googlecodelabs/android-navigation/blob/master/app/src/main/java/com/example/android/codelabs/navigation/HomeFragment.kt"><strong>HomeFragment.kt</strong></a></p>
</li>
<li><p>Hook up the <strong><code>navigate_destination_button</code></strong> in <strong><code>onViewCreated()</code></strong></p>
</li>
<li><p>Run the app and click the <strong>Navigate To Destination</strong> button. Note that the button navigates to the <strong><code>flow_step_one_dest</code></strong> destination.</p>
</li>
</ol>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/0d320fca-b646-4877-ac35-76ed0204161d/image.png" alt=""></p>
<blockquote>
<p>You can also use the convenience method <a href="https://developer.android.com/reference/kotlin/androidx/navigation/Navigation#createNavigateOnClickListener%28kotlin.Int%2C+android.os.Bundle%29"><strong>Navigation.createNavigateOnClickListener(@IdRes destId: Int, bundle: Bundle)</strong></a>. This method will build an <strong>OnClickListener</strong> to navigate to the given destination with a bundle of arguments to be passed to the destination.</p>
<p>The click listener code would look like this:
<img src="https://images.velog.io/images/dmitry-_-11/post/561025d0-dc1c-4d37-9d39-3e998006187a/image.png" alt=""></p>
</blockquote>
<h2 id="5-changing-the-navigation-transition">5. Changing the Navigation Transition</h2>
<hr>
<p>Each <strong><code>navigate()</code></strong> call has a not very exciting default transition associated with it, as seen below:</p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/bfd92d1e-32b8-4f73-9cc0-7f235c90d5f2/ff5077b816fd01ed.gif" alt=""></p>
<p>The default transition, as well as other attributes associated with the call, can be overridden by including a set of <strong><code>NavOptions</code></strong>. <strong><code>NavOptions</code></strong> uses a <strong><code>Builder</code></strong> pattern which allows you to override and set only the options you need. There&#39;s also a ktx DSL for NavOptions, which is what you&#39;ll be using.</p>
<p>For animated transitions, you can define XML animation resources in the <strong><a href="https://github.com/googlecodelabs/android-navigation/tree/master/app/src/main/res/anim">anim</a></strong> resource folder and then use those animations for transitions. Some examples are included in the app code:</p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/3044b1ae-da39-4b45-a738-cd529e3320f2/image.png" alt=""></p>
<h3 id="add-a-custom-transition">Add a Custom Transition</h3>
<p>Update the code so that pressing the <strong>Navigate To Destination</strong> button shows a custom transition animation.</p>
<ol>
<li><p>Open <strong><a href="https://github.com/googlecodelabs/android-navigation/blob/master/app/src/main/java/com/example/android/codelabs/navigation/HomeFragment.kt">HomeFragment.kt</a></strong></p>
</li>
<li><p>Define a <strong><code>NavOptions</code></strong> and pass it into the <strong><code>navigate()</code></strong> call to <strong><code>navigate_destination_button</code></strong></p>
</li>
<li><p>Remove the code added in step 5, if it&#39;s still there</p>
</li>
<li><p>Verify that tapping the <strong>Navigate To Destination</strong> button causes the fragment to slide onto the screen and back causes it to slide off the screen</p>
</li>
</ol>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/8b9ebfa1-bab1-4fb1-be84-2e777e2d0bf2/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/96ddb6e7-61f2-4219-9a71-1dcf1341b7dc/270eb2b99ea0475e.gif" alt=""></p>
<h2 id="6-navigate-using-actions">6. Navigate using actions</h2>
<hr>
<h3 id="actions">Actions</h3>
<p>The navigation system also allows you to navigate via <em>actions</em>. As previously mentioned, the lines shown in the navigation graph are visual representations of actions.</p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/84be1028-f792-43af-a9ea-3a0ae015c589/image.png" alt=""></p>
<p>Navigation by actions has the following benefits over navigation by destination:</p>
<ul>
<li><p>You can visualize the navigation paths through your app</p>
</li>
<li><p>Actions can contain additional associated attributes you can set, such as a transition animation, arguments values, and backstack behavior</p>
</li>
<li><p>You can use the plugin safe args to navigate, which you&#39;ll see shortly</p>
</li>
</ul>
<p>Here&#39;s the visual and XML for the action that connects <strong><code>flow_step_one_dest</code></strong> and <strong><code>flow_step_two_dest</code></strong>:</p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/1f2a9a96-7527-4002-a183-3215c294bc1a/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/a706547e-ff61-4951-95ca-4e042b2a6992/image.png" alt=""></p>
<p>Notice:</p>
<ul>
<li><p>The actions are nested within the destination - this is the destination you will navigate from</p>
</li>
<li><p>The action includes a destination argument referring to <strong><code>flow_step_two_dest</code></strong>; this is the ID of where you will navigate to</p>
</li>
<li><p>The ID for the action is <strong><code>next_action</code></strong></p>
</li>
</ul>
<p>Here is another example of the action connecting <strong><code>flow_step_two_dest</code></strong> to <strong><code>home_dest</code></strong></p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/4a97daa4-f4ae-448a-9419-52584ec541c4/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/f4a7da65-7f44-4ee7-8b6f-b6f23efc474c/image.png" alt=""></p>
<p>Notice:</p>
<ul>
<li><p>The same ID <strong><code>next_action</code></strong> is used for the action connecting <strong><code>flow_step_two_dest</code></strong> to <strong><code>home_dest</code></strong>. You can navigate using the <strong><code>next_action</code></strong> id from either <strong><code>flow_step_one_dest</code></strong> or <strong><code>flow_step_two_dest</code></strong>. This is an example of how actions can provide a level of abstraction and can navigate your somewhere different depending on context.</p>
</li>
<li><p>The <strong><code>popUpTo</code></strong> attribute is used - this action will pop fragments off of the back-stack until you reach <strong><code>home_dest</code></strong></p>
</li>
</ul>
<h3 id="navigate-with-an-action">Navigate with an Action</h3>
<p>Time to hook up the <strong>Navigate with Action</strong> button so that it lives up to its name!</p>
<ol>
<li><p>Open the <strong><a href="https://github.com/googlecodelabs/android-navigation/blob/master/app/src/main/res/navigation/mobile_navigation.xml">mobile_navigation.xml</a></strong> file in <strong>Design</strong> mode</p>
</li>
<li><p>Drag an arrow from <strong><code>home_dest</code></strong> to <strong><code>flow_step_two_dedst</code></strong>:<img src="https://images.velog.io/images/dmitry-_-11/post/e193b27d-4010-4f91-bab9-3a2841319e74/image.png" alt=""></p>
</li>
<li><p>With the action arrow selected change the properties of the action so that:
<img src="https://images.velog.io/images/dmitry-_-11/post/518e1666-41db-4a88-971e-ff9d915360ae/image.png" alt=""></p>
</li>
<li><p>Click the <strong>Text</strong> tab
<img src="https://images.velog.io/images/dmitry-_-11/post/c2691609-7cff-495e-b9fb-dd90d30cdd01/image.png" alt="">Note the newly added <strong><code>next_action</code></strong> action under the <strong><code>home_dest</code></strong> destination.</p>
</li>
<li><p>Open <strong><a href="https://github.com/googlecodelabs/android-navigation/blob/master/app/src/main/java/com/example/android/codelabs/navigation/HomeFragment.kt">HomeFragment.kt</a></strong></p>
</li>
<li><p>Add a click listener to the <strong><code>navigate_action_button</code></strong>
<img src="https://images.velog.io/images/dmitry-_-11/post/9f182608-9268-4fc3-b33a-c0260998b65c/image.png" alt=""></p>
<blockquote>
<p>Actions allow you to attach <strong>NavOptions</strong> in the navigation XML file, rather than specifying them programmatically.</p>
</blockquote>
</li>
<li><p>Verify that tapping the <strong>Navigate To Action</strong> now navigates to the next screen.</p>
</li>
</ol>
<h2 id="7-using-safe-args-for-navigation">7. Using safe args for navigation</h2>
<hr>
<h3 id="safe-args">Safe Args</h3>
<p>The navigation component has a Gradle plugin, called <a href="https://developer.android.com/topic/libraries/architecture/navigation/navigation-pass-data#Safe-args">safe args</a>, that generates simple object and builder classes for type-safe access to arguments specified for destinations and actions.</p>
<p>Safe args allows you to get rid of code like this when passing values between destinations:</p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/55cce1a0-a6b4-4a45-afa0-ff228f17c097/image.png" alt=""></p>
<p>And, instead, replace it with code that has generated setters and getters.</p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/b1130170-0c57-49bb-a2db-c13dc20f0907/image.png" alt=""></p>
<blockquote>
<p>Because of its type safety, navigation using safe args generated classes is the preferred way to navigate by action and pass arguments during navigation.</p>
</blockquote>
<h3 id="pass-a-value-using-safe-args">Pass a value using safe args</h3>
<ol>
<li><p>Open the project <strong><code>build.gradle</code></strong> file and notice the safe args plugin:</p>
<blockquote>
<h4 id="buildgradle">build.gradle</h4>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/f2edbd90-6cfa-4e4b-ae51-a7e5e111b762/image.png" alt=""></p>
</blockquote>
</li>
<li><p>Open the <strong><code>app/build.gradle</code></strong> file and notice the applied plugin:</p>
<blockquote>
<h4 id="appbuildgradle">app/build.gradle</h4>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/96510b42-280b-48d5-a3c2-ddbca8d343ea/image.png" alt=""></p>
</blockquote>
</li>
<li><p>Open <strong><code>mobile_navigation.xml</code></strong> and notice how arguments are defined in the <strong><code>flow_step_one_dest</code></strong> destination.</p>
<blockquote>
<h4 id="mobile_navigationxml">mobile_navigation.xml</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/86447c59-2dd8-4efa-9d6d-dd9757d9b56b/image.png" alt=""> </p>
<blockquote>
</blockquote>
<p>Using the <strong><code>&lt;argument&gt;</code></strong> tag, safeargs generates a class called <strong><code>FlowStepFragmentArgs</code></strong>.</p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/71bac611-5e5f-4d0a-baeb-b18cd2362f2f/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>Since the XML includes <strong><code>argument</code></strong> called <strong><code>flowStepNumber</code></strong>, specified by <strong><code>android:name=&quot;flowStepNumber&quot;</code></strong>, the generated class <strong><code>FlowStepFragmentArgs</code></strong> will include variable <strong><code>flowStepNumber</code></strong> with getters and setters.</p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/7fdeb1b1-b845-416a-8b51-2addf6ed7c66/image.png" alt=""></p>
</li>
<li><p>Open <strong><code>FlowStepFragment.kt</code></strong></p>
</li>
<li><p>Comment out the line of code shown below:</p>
<blockquote>
<h4 id="flowstepfragmentkt">FlowStepFragment.kt</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/e7a6c423-029b-46db-9d9b-f6a69b119ac3/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>This old-style code is not type-safe. It&#39;s better to use safe args.</p>
</li>
<li><p>Update <strong><code>FlowStepFragment</code></strong> to use the code generated class <strong><code>FlowStepFragmentArgs</code></strong>. This will get the <strong><code>FlowStepFragment</code></strong> arguments in a type-safe manner:</p>
<blockquote>
<h4 id="flowstepfragmentkt-1">FlowStepFragment.kt</h4>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/9421c7c6-4068-4457-97c4-8704b188e94e/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/75e48831-c72a-4603-8a37-472c311d4054/image.png" alt=""></p>
</li>
</ol>
<h3 id="safe-args-direction-classes">Safe Args Direction classes</h3>
<p>You can also use safe args to navigate in a type safe way, with or without adding arguments. You do this using the generated Directions classes.</p>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/7dcf5fd5-44ed-48e8-886e-f0eca18193f7/image.png" alt=""></p>
<p>Directions classes are generated for every distinct destination with actions. The Directions class includes methods for every action a destination has.</p>
<p>For example, the <strong><code>navigate_action_button</code></strong> click listener in HomeFragment.kt could be changed to:</p>
<h4 id="homefragmentkt">HomeFragment.kt</h4>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/8ba67834-da9d-4823-b67e-88470439431f/image.png" alt=""></p>
<blockquote>
<p>Note that in your navigation graph XML you can provide a <strong>defaultValue</strong> for each argument. If you do <em>not</em> then you <strong>must</strong> pass the argument into the action, as shown:
<img src="https://images.velog.io/images/dmitry-_-11/post/5d88442c-6c04-4f4e-9d16-ae73b1715aad/image.png" alt=""></p>
<p><strong>HomeFragmentDirections.nextAction(flowStepNumberArg)</strong></p>
</blockquote>
<h2 id="next--jetpack-navigation-02"><a href="https://velog.io/@dmitry-_-11/Jetpack-Navigation-02">Next | Jetpack Navigation 02</a></h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[Kotlin Comparable<T>]]></title>
            <link>https://velog.io/@dmitry-_-11/Kotlin-ComparableT</link>
            <guid>https://velog.io/@dmitry-_-11/Kotlin-ComparableT</guid>
            <pubDate>Sun, 31 Jan 2021 11:05:04 GMT</pubDate>
            <description><![CDATA[<h2 id="comparablet-interface">Comparable&lt;T&gt; Interface</h2>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/18cd1652-15a3-4880-8624-21bd72e54b35/image.png" alt=""></p>
<h2 id="implementation-example">Implementation Example</h2>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/20f58566-7b99-4800-a23a-3cccd6a4426f/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Kotlic Collections 02 - Sequences]]></title>
            <link>https://velog.io/@dmitry-_-11/Kotlic-Collections-02-Sequences</link>
            <guid>https://velog.io/@dmitry-_-11/Kotlic-Collections-02-Sequences</guid>
            <pubDate>Thu, 28 Jan 2021 12:53:28 GMT</pubDate>
            <description><![CDATA[<p>Along with collections, the Kotlin standard library contains another container type – sequences <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/-sequence/index.html">(Sequence&lt;T&gt;)</a>. Sequences offer the same functions as <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-iterable/index.html">Iterable</a> but implement another approach to multi-step collection processing.</p>
<blockquote>
<h3 id="iterable-vs-sequence">Iterable vs Sequence</h3>
<h4 id="iterable">Iterable</h4>
</blockquote>
<ul>
<li>Multi-step processing of iterables is executed <strong>eagerly</strong>.<blockquote>
</blockquote>
</li>
<li>Each processing step completes and retruns its result - an intermediate collection.<blockquote>
</blockquote>
</li>
<li>The following step executes on this collection(an intermediate collection).<image src="https://images.velog.io/images/dmitry-_-11/post/13c23fdc-0b6e-4cd7-b343-86d975ff91fb/image.png"/>
>
></li>
<li>The order of operations execution :<blockquote>
</blockquote>
<ul>
<li><strong><code>Iterable</code></strong> completes each step for the whole collection and then proceeds to the next step.<blockquote>
<h4 id="sequence">Sequence</h4>
</blockquote>
</li>
</ul>
</li>
<li>Multi-step processing of sequences is executed <strong>lazily</strong> when possible.<blockquote>
</blockquote>
</li>
<li>Actual computing happens only when the result of the whole processing chain is requested.<blockquote>
</blockquote>
</li>
<li>The order of operations execution:<blockquote>
</blockquote>
<ul>
<li><strong><code>Sequence</code></strong> performs all the processing steps one-by-one for every single element.</li>
</ul>
</li>
</ul>
<p>So, the sequences let you avoid building results of intermediate steps, therefore improving the performance of the whole collection processing chain. However, the lazy nature of sequences adds some overhead which may be significant when processing smaller collections or doing simpler computations. Hence, you should consider both <strong><code>Sequence</code></strong> and <strong><code>Iterable</code></strong> and decide which one is better for your case.</p>
<h2 id="constructing">Constructing</h2>
<hr>
<h3 id="from-elements">From elements</h3>
<p>To create a sequence, call the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/sequence-of.html">sequenceOf()</a> function listing the elements as its arguments:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/0d071e8f-0ab2-492f-960a-b52cf2e27d3d/image.png" />

<h3 id="from-iterable">From Iterable</h3>
<p>If you already have an <strong><code>Iterable</code></strong> object (such as a <strong><code>List</code></strong> or a <strong><code>Set</code></strong>), you can create a sequence from it by calling <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/as-sequence.html">asSequence()</a>:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/4dd20f55-d305-415a-94c9-91328934ea70/image.png" />

<h3 id="from-function">From function</h3>
<p>One more way to create a sequence is by building it with a function that calculates its elements. To build a sequence based on a function, call <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/generate-sequence.html">generateSequence()</a> with this function as an argument. Optionally, you can specify the first element as an explicit value or a result of a function call. The sequence generation stops when the provided function returns <strong><code>null</code></strong>. So, the sequence in the example below is infinite:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/dabb301d-619d-4bf1-af29-5d7a539bf6da/image.png" />

<p>To create a finite sequence with <strong><code>generateSequence()</code></strong>, provide a function that returns <strong><code>null</code></strong> after the last element you need:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/5adb75f2-5327-4eb3-892c-7613ebd39573/image.png" />

<blockquote>
<h3 id="note--generatesequence--generatorsequence-class">Note : <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/generate-sequence.html">generateSequence()</a> &amp; <a href="https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/kotlin/collections/Sequences.kt">GeneratorSequence class</a></h3>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/9bcc9f30-2303-486d-a527-45b0a5ac7b3c/image.png" alt=""><img src="https://images.velog.io/images/dmitry-_-11/post/bec3711e-6566-4b71-bfb3-99b0110708e6/image.png" alt=""><img src="https://images.velog.io/images/dmitry-_-11/post/1cde9ecd-c81b-4b9f-97af-c6df97e40e5e/image.png" alt=""><img src="https://images.velog.io/images/dmitry-_-11/post/0780207d-0b3a-4376-b489-c75ce21dc090/image.png" alt=""></p>
</blockquote>
<h3 id="from-chunks">From chunks</h3>
<image src="https://images.velog.io/images/dmitry-_-11/post/55a7a471-815b-4788-b7f7-d1d17c3119fb/image.png" />

<p>Finally, there is a function that lets you produce sequence elements one by one or by chunks of arbitrary sizes - the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/sequence.html">sequence()</a> function. This function takes a lambda expression containing calls of <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/-sequence-scope/yield.html">yield()</a> and <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/-sequence-scope/yield-all.html">yieldAll()</a> functions. They return an element to the sequence consumer and suspend the execution of <strong><code>sequence()</code></strong> until the next element is requested by the consumer.</p>
<ul>
<li><p><strong><code>yield()</code></strong> takes a single element as an argument</p>
</li>
<li><p><strong><code>yieldAll()</code></strong> can take</p>
<ul>
<li><p>an <strong><code>Iterable</code></strong> object,</p>
</li>
<li><p>an <strong><code>Iterator</code></strong>,</p>
</li>
<li><p>or another <strong><code>Sequence</code></strong> (it can be infinite - <strong>such a call must be the last: all subsequent calls will never be executed</strong>).</p>
</li>
</ul>
</li>
</ul>
<h2 id="sequence-operations">Sequence operations</h2>
<p>The sequence operations can be classified into the following groups regarding their state requirements:</p>
<ul>
<li><p><em>Stateless</em> operations require no state and process each element independently, for example, <a href="https://kotlinlang.org/docs/reference/collection-transformations.html#mapping">map()</a> or <a href="https://kotlinlang.org/docs/reference/collection-filtering.html">filter()</a>. Stateless operations can also require a small constant amount of state to process an element, for example, <a href="https://kotlinlang.org/docs/reference/collection-parts.html">take() or drop()</a>.</p>
</li>
<li><p><em>Stateful</em> operations require a significant amount of state, usually proportional to the number of elements in a sequence.</p>
</li>
</ul>
<p>If a sequence operation returns another sequence, which is produced lazily, it&#39;s called <em>intermediate</em>. Otherwise, the operation is <em>terminal</em>. Examples of terminal operations are <a href="https://kotlinlang.org/docs/reference/constructing-collections.html#copying">toList()</a> or <a href="https://kotlinlang.org/docs/reference/collection-aggregate.html">sum()</a>. Sequence elements can be retrieved only with terminal operations.</p>
<p>Sequences can be iterated multiple times; however some sequence implementations might constrain themselves to be iterated only once. That is mentioned specifically in their documentation.</p>
<h2 id="sequence-processing-example">Sequence processing example</h2>
<hr>
<p>Let&#39;s take a look at the difference between <strong><code>Iterable</code></strong> and <strong><code>Sequence</code></strong> with an example.</p>
<h3 id="iterable-1">Iterable</h3>
<p>Assume that you have a list of words. The code below filters the words longer than three characters and prints the lengths of first four such words.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/0a36e471-38bf-4578-97b6-008e4af9b193/image.png" />

<image src="https://images.velog.io/images/dmitry-_-11/post/b5c0ed68-cbd8-41cd-bf29-c0c40ffc53ca/image.png" />

<p>When you run this code, you&#39;ll see that the <strong><code>filter()</code></strong> and <strong><code>map()</code></strong> functions are executed in the same order as they appear in the code. First, you see <strong><code>filter</code></strong>: for all elements, then <strong><code>length</code></strong>: for the elements left after filtering, and then the output of the two last lines. This is how the list processing goes:
<img src="https://images.velog.io/images/dmitry-_-11/post/118245cb-d675-47e8-9d31-7b55c6304425/image.png" alt=""></p>
<h3 id="sequence-1">Sequence</h3>
<p>Now let&#39;s write the same with sequences:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/aa5b1644-3537-4ddd-8f05-2955afe26517/image.png" />

<image src="https://images.velog.io/images/dmitry-_-11/post/c6f98566-a8ca-40a3-80f7-fd3fe4930f0b/image.png" />

<p>The output of this code shows that the <strong><code>filter()</code></strong> and <strong><code>map()</code></strong> functions are called only when building the result list. So, you first see the line of text <strong><code>“Lengths of..”</code></strong> and then the sequence processing starts. Note that for elements left after filtering, the map executes before filtering the next element. When the result size reaches 4, the processing stops because it&#39;s the largest possible size that <strong><code>take(4)</code></strong> can return.</p>
<p>The sequence processing goes like this:
<img src="https://images.velog.io/images/dmitry-_-11/post/3e65ae01-bca5-4550-9fbf-2d7aac5f1053/image.png" alt="">In this example, the sequence processing takes 18 steps instead of 23 steps for doing the same with lists.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Kotlic Collections 01 - Collection, List, Map, Set]]></title>
            <link>https://velog.io/@dmitry-_-11/Kotlic-Collections-01-Collection-List-Map-Set</link>
            <guid>https://velog.io/@dmitry-_-11/Kotlic-Collections-01-Collection-List-Map-Set</guid>
            <pubDate>Tue, 26 Jan 2021 12:43:51 GMT</pubDate>
            <description><![CDATA[<h2 id="collection-types">Collection types</h2>
<hr>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/180c21e2-fb83-4f1f-a9b1-b6d1cb947d08/image.png" alt="">
The Kotlin Standard Library provides implementations for basic collection types: sets, lists, and maps. A pair of interfaces represent each collection type:</p>
<ul>
<li>A <strong>read-only</strong> interface that provides operations for accessing collection elements.</li>
<li>A <strong>mutable</strong> interface that extends the corresponding read-only interface with write operations: adding, removing, and updating its elements.</li>
</ul>
<p>Note that altering a mutable collection doesn&#39;t require it to be a <strong><code>var</code></strong>: write operations modify the same mutable collection object, so the reference doesn&#39;t change. Although, if you try to reassign a <strong><code>val</code></strong> collection, you&#39;ll get a compilation error.</p>
<p>The read-only collection types are <a href="https://kotlinlang.org/docs/reference/generics.html#variance">covariant</a>. This means that, if a <strong><code>Rectangle</code></strong> class inherits from <strong><code>Shape</code></strong>, you can use a <strong><code>List&lt;Rectangle&gt;</code></strong> anywhere the <strong><code>List&lt;Shape&gt;</code></strong>is required. In other words, the collection types have the same subtyping relationship as the element types. Maps are covariant on the value type, but not on the key type.</p>
<p>In turn, mutable collections aren&#39;t covariant; otherwise, this would lead to runtime failures. If <strong><code>MutableList&lt;Rectangle&gt;</code></strong>was a subtype of <strong><code>MutableList&lt;Shape&gt;</code></strong>, you could insert other <strong><code>Shape</code></strong> inheritors (for example, <strong><code>Circle</code></strong>) into it, thus violating its <strong><code>Rectangle</code></strong> type argument.</p>
<h2 id="get-familiar-with-collections">Get familiar with collections</h2>
<hr>
<h3 id="collection">Collection</h3>
<image src="https://images.velog.io/images/dmitry-_-11/post/26025e8c-f74d-409f-9990-a77f9d79cd05/image.png" />

<image src="https://images.velog.io/images/dmitry-_-11/post/4a8b52f2-996a-4976-be5f-ff731631e658/image.png" />


<h3 id="list">List</h3>
<image src="https://images.velog.io/images/dmitry-_-11/post/ed114bda-e5d3-48a5-8f40-c741fcb42230/image.png" />

<image src="https://images.velog.io/images/dmitry-_-11/post/540b954e-3bd2-4208-8e3f-beb861659e73/image.png" />

<image src="https://images.velog.io/images/dmitry-_-11/post/781fc7f6-878e-42f1-abce-07abeef57c1b/image.png" />

<p>As you see, in some aspects lists are very similar to arrays. However, there is one important difference: an array&#39;s size is defined upon initialization and is never changed; in turn, a list doesn&#39;t have a predefined size; a list&#39;s size can be changed as a result of write operations: adding, updating, or removing elements.</p>
<p>In Kotlin, the default implementation of <strong><code>List</code></strong> is <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-array-list/">ArrayList</a> which you can think of as a resizable array.</p>
<h3 id="set">Set</h3>
<image src="https://images.velog.io/images/dmitry-_-11/post/7c1b552d-60e2-4d76-923d-57b4777b006e/image.png" />

<p><a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-set/index.html">Set&lt;T&gt;</a> stores unique elements; their order is generally undefined. <strong><code>null</code></strong> elements are <strong>unique</strong> as well: a <strong><code>Set</code></strong> can contain only one <strong><code>null</code></strong>. Two sets are equal if they have the same size, and for each element of a set there is an equal element in the other set.</p>
<p><a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-set/index.html">MutableSet</a> is a <strong><code>Set</code></strong> with write operations from <strong><code>MutableCollection</code></strong>.</p>
<p>The default implementation of <strong><code>Set</code></strong> – <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-linked-hash-set/index.html">LinkedHashSet</a> – preserves the order of elements insertion. Hence, the functions that rely on the order, such as <strong><code>first()</code></strong> or <strong><code>last()</code></strong>, return predictable results on such sets.</p>
<p>An alternative implementation – <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-hash-set/index.html">HashSet</a> – says nothing about the elements order, so calling such functions on it returns unpredictable results. However, <strong><code>HashSet</code></strong> requires less memory to store the same number of elements.</p>
<h3 id="map">Map</h3>
<p><a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/index.html">Map&lt;K, V&gt;</a> is not an inheritor of the <strong><code>Collection</code></strong> interface; however, it&#39;s a Kotlin collection type as well. A <strong><code>Map</code></strong> stores <em>key-value</em> pairs (or <em>entries</em>); keys are unique, but different keys can be paired with equal values. The <strong><code>Map</code></strong> interface provides specific functions, such as access to value by key, searching keys and values, and so on.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/eb20fa5b-a035-4c48-ad89-2192089eab1f/image.png" />

<p><a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-map/index.html">MutableMap</a> is a <strong><code>Map</code></strong> with map write operations, for example, you can add a new key-value pair or update the value associated with the given key.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/89f0de13-5e00-481b-a110-f25b28a76266/image.png" />

<p>The default implementation of <strong><code>Map</code></strong> – <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-linked-hash-map/index.html">LinkedHashMap</a> – preserves the order of elements insertion when iterating the map. In turn, an alternative implementation – <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-hash-map/index.html">HashMap</a> – says nothing about the elements order.</p>
<h2 id="constructing-collections">Constructing Collections</h2>
<hr>
<h3 id="constructing-from-elements">Constructing from elements</h3>
<image src="https://images.velog.io/images/dmitry-_-11/post/c4c506a8-4932-4c13-988f-4428a053e3c2/image.png"/>


<p>The most common way to create a collection is with the standard library functions <code>listOf&lt;T&gt;()</code>, <code>setOf&lt;T&gt;()</code>, <code>mutableListOf&lt;T&gt;()</code>, <code>mutableSetOf&lt;T&gt;()</code>. If you provide a comma-separated list of collection elements as arguments, the compiler detects the element type automatically. When creating empty collections, specify the type explicitly.</p>
<p>The same is available for maps with the functions<code>mapOf()</code> and <code>mutableMapOf()</code>. The map&#39;s keys and values are passed as <code>Pair</code> objects (usually created with <code>to</code> infix function).</p>
<p>Note that the to notation creates a short-living <code>Pair</code> object, so it&#39;s recommended that you use it only if performance isn&#39;t critical. To avoid excessive memory usage, use alternative ways. For example, you can create a mutable map and populate it using the write operations. The <a href="https://kotlinlang.org/docs/reference/scope-functions.html#apply">apply()</a> function can help to keep the initialization fluent here.</p>
<h3 id="empty-collections">Empty collections</h3>
<image src="https://images.velog.io/images/dmitry-_-11/post/bde2303f-a988-4807-a73b-023721d2dc04/image.png" />

<h3 id="initializer-functions-for-lists">Initializer functions for lists</h3>
<image src="https://images.velog.io/images/dmitry-_-11/post/e9fd41be-b1b9-4587-8eb3-49dab86d2245/image.png" />

<p>For lists, there is a constructor that takes the list size and the initializer function that defines the element value based on its index.</p>
<h4 id="note-list--listof">Note: <strong><code>List()</code></strong> &amp; <strong><code>listOf()</code></strong></h4>
<image src="https://images.velog.io/images/dmitry-_-11/post/06de30c4-f4ca-4bf7-afd2-f00a40fc20fe/image.png"/>
<image src="https://images.velog.io/images/dmitry-_-11/post/78398eed-6445-43fb-bc4a-afc7835fd5f3/image.png" />
<image src="https://images.velog.io/images/dmitry-_-11/post/b9eb032c-2f3c-4baa-8de8-4dfc8fd37881/image.png" />
<image src="https://images.velog.io/images/dmitry-_-11/post/b9c3a187-33f3-4f40-83d4-321edc65018b/image.png" />

<h3 id="concreate-type-constructors">Concreate type constructors</h3>
<image src="https://images.velog.io/images/dmitry-_-11/post/32e2f59c-4b1c-44fc-a470-ac9d8d1c9ea0/image.png" />

<p>To create a concrete type collection, such as an <strong><code>ArrayList</code></strong> or <strong><code>LinkedList</code></strong>, you can use the available constructors for these types. Similar constructors are available for implementations of <strong><code>Set</code></strong> and <strong><code>Map</code></strong>.</p>
<h3 id="copying">Copying</h3>
<p>To create a collection with the same elements as an existing collection, you can use copying operations. Collection copying operations from the standard library create shallow copy collections with references to the same elements. Thus, a change made to a collection element reflects in all its copies.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/3cdbb9c5-f2ff-4d79-9bbf-61dc2bd96666/image.png" />

<p>Collection copying functions, such as <code>toList()</code>, <code>toMutableList()</code>, <code>toSet()</code> and others, create a snapshot of a collection at a specific moment. Their result is a new collection of the same elements. If you add or remove elements from the original collection, this won&#39;t affect the copies. Copies may be changed independently of the source as well. These functions can also be used for converting collections to other types, for example, build a set from a list or vice versa.
<br/></p>
<image src="https://images.velog.io/images/dmitry-_-11/post/1b05ec7b-d638-4d2d-ac10-89d546790389/image.png" />
Alternatively, you can create new references to the same collection instance. New references are created when you initialize a collection variable with an existing collection. So, when the collection instance is altered through a reference, the changes are reflected in all its references.

<p>Collection initialization can be used for restricting mutability. For example, if you create a <strong><code>List</code></strong> reference to a <strong><code>MutableList</code></strong>, the compiler will produce errors if you try to modify the collection through this reference.</p>
<h3 id="invoking-functions-on-other-collections">Invoking functions on other collections</h3>
<p>Collections can be created in result of various operations on other collections. For example, <a href="https://kotlinlang.org/docs/reference/collection-filtering.html">filtering</a> a list creates a new list of elements that match the filter:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/3ea9c02b-1128-402b-9a41-023713c3585c/image.png" />


<p><a href="https://kotlinlang.org/docs/reference/collection-transformations.html#mapping">Mapping</a> produces a list of a transformation results:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/67a0701f-c8ad-4e20-b76e-3742d9ab904e/image.png" />


<p><a href="https://kotlinlang.org/docs/reference/collection-transformations.html#association">Association</a> produces maps:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/1cbe73ca-4d2b-4cae-8362-3c1d116b9e84/image.png" />

<h2 id="iterators">Iterators</h2>
<hr>
<p>For traversing collection elements, the Kotlin standard library supports the commonly used mechanism of iterators – objects that provide access to the elements sequentially without exposing the underlying structure of the collection. Iterators are useful when you need to process all the elements of a collection one-by-one, for example, print values or make similar updates to them.</p>
<p>Iterators can be obtained for inheritors of the <strong><code>Iterable&lt;T&gt;</code></strong> interface, including <strong><code>Set</code></strong> and <strong><code>List</code></strong>, by calling the <code>iterator()</code> function. Once you obtain an iterator, it points to the first element of a collection; calling the <code>next()</code> function returns this element and moves the iterator position to the following element if it exists.</p>
<blockquote>
<p>*<em>Note : *</em>Once the iterator passes through the last element, it can no longer be used for retrieving elements; neither can it be reset to any previous position. To iterate through the collection again, create a new iterator.</p>
</blockquote>
<image src="https://images.velog.io/images/dmitry-_-11/post/856e0b8b-b1a6-4961-8008-5257e2603e5e/image.png"/>

<p>Another way to go through an <strong><code>Iterable</code></strong> collection is the well-known <code>for</code> loop. When using <code>for</code> on a collection, you obtain the iterator implicitly. So, the following code is equivalent to the example above:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/87c8532e-1969-4fba-bc50-ea083a99c82e/image.png" />

<p>Finally, there is a useful <code>forEach()</code> function that lets you automatically iterate a collection and execute the given code for each element. So, the same example would look like this:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/7ec1dc90-63c3-4f73-80be-6e025b9b7e26/image.png" />

<h3 id="list-iterators">List iterators</h3>
<p>For lists, there is a special iterator implementation: <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list-iterator/index.html">ListIterator</a>. <strong>It supports iterating lists in both directions: forwards and backwards</strong>. Backward iteration is implemented by the functions <code>hasPrevious()</code> and <code>previous()</code>. Additionally, the <strong><code>ListIterator</code></strong> provides information about the element indices with the functions <code>nextIndex()</code> and <code>previousIndex()</code>.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/0ef98912-4e75-42c0-b2e6-3db5e23f8ec9/image.png" />

<p>Having the ability to iterate in both directions, means the <strong><code>ListIterator</code></strong> can still be used after it reaches the last element.</p>
<h3 id="mutable-iterators">Mutable iterators</h3>
<p>For iterating mutable collections, there is <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-iterator/index.html">MutableIterator</a> that extends <strong><code>Iterator</code></strong> with the element removal function <code>remove()</code>. So, you can remove elements from a collection while iterating it.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/476db287-b98e-484c-bfeb-7530015361ad/image.png" />

<p>In addition to removing elements, the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-iterator/index.html">MutableIterator</a> can also insert and replace elements while iterating the list.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/5c0ef60a-1598-4a61-ac21-47ede1a097e8/image.png" />

<h2 id="ranges-and-progressions">Ranges and Progressions</h2>
<hr>
<p>Kotlin lets you easily create ranges of values using the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/range-to.html">rangeTo()</a> function from the <code>kotlin.ranges</code> package and its operator form <code>..</code>. Usually, <code>rangeTo()</code> is complemented by <code>in</code> or <code>!in</code> functions:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/a6d773ea-04a0-47c6-abc3-f6ac3001b124/image.png" />

<p>Integral type ranges (<a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/-int-range/index.html">IntRange</a>, <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/-long-range/index.html">LongRange</a>, <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/-char-range/index.html">CharRange</a>) have an extra feature: they can be iterated over. These ranges are also <a href="https://en.wikipedia.org/wiki/Arithmetic_progression">progressions</a> of the corresponding integral types. Such ranges are generally used for iteration in the <code>for</code> loops:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/422fb767-6295-4ad6-9d0b-e655a02c9ecd/image.png" />

<p>To iterate numbers in reverse order, use the <code>downTo</code> function instead of <code>..</code>:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/04964e5c-ba61-4b2d-bf4b-b6e466979893/image.png" />

<p>It is also possible to iterate over numbers with an arbitrary step (not necessarily 1). This is done via the <code>step</code> function:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/8d58f084-5fe9-4675-8ad5-2a0451c77584/image.png" />

<p>To iterate a number range which does not include its end element, use the <code>until</code> function:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/dcb93223-2376-415e-bde5-1b8467e2b9d4/image.png" />

<h3 id="range">Range</h3>
<p>A range defines a closed interval in the mathematical sense: it is defined by its two endpoint values which are both included in the range. Ranges are defined for comparable types: having an order, you can define whether an arbitrary instance is in the range between two given instances. The main operation on ranges is <code>contains</code>, which is usually used in the form of <code>in</code> and <code>!in</code> operators.</p>
<p>To create a range for your class, call the <code>rangeTo()</code> function on the range start value and provide the end value as an argument. <code>rangeTo()</code> is often called in its operator form <code>..</code>.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/8e9440d5-872a-4c83-ac4d-3fa482557e52/image.png" />

<h3 id="progression">Progression</h3>
<p>As shown in the examples above, the ranges of integral types, such as <code>Int</code>, <code>Long</code>, and <code>Char</code>, can be treated as <a href="https://en.wikipedia.org/wiki/Arithmetic_progression">arithmetic progressions</a> of them. In Kotlin, these progressions are defined by special types: <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/-int-progression/index.html">IntProgression</a>, <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/-long-progression/index.html">LongProgression</a>, and <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/-char-progression/index.html">CharProgression</a>.</p>
<p>Progressions have three essential properties: the <code>first</code> element, the <code>last</code> element, and a non-zero <code>step</code>. The first element is <code>first</code>, subsequent elements are the previous element plus a <code>step</code>. Iteration over a progression with a positive step is equivalent to an indexed <code>for</code> loop in Java/JavaScript.</p>
<pre><code class="language-java">for (int i = first; i &lt;= last; i += step) {
    // ...
}</code></pre>
<p>When you create a progression implicitly by iterating a range, this progression&#39;s <code>first</code> and <code>last</code> elements are the range&#39;s endpoints, and the <code>step</code> is 1.</p>
<pre><code class="language-kotlin">for (i in 1..10) print(i)</code></pre>
<p>To define a custom progression step, use the <code>step</code> function on a range.</p>
<pre><code class="language-kotlin">for (i in 1..8 step 2) print(i)</code></pre>
<p>The <code>last</code> element of the progressions is calculated this way:</p>
<ul>
<li><p>For a positive step: the maximum value not greater than the end value such that: 
<code>(last - first) % step == 0</code>.</p>
</li>
<li><p>For a negative step: the minimum value not less than the end value such that:
<code>(last - first) % step == 0</code>.</p>
</li>
</ul>
<p>Thus, the <code>last</code> element is not always the same as the specified end value.</p>
<pre><code class="language-kotlin">for (i in 1..9 step 3) print(i) // the last element is 7</code></pre>
<p>To create a progression for iterating in reverse order, use <code>downTo</code> instead of <code>..</code> when defining the range for it.</p>
<pre><code class="language-kotlin">for (i in 4 downTo 1) print(i)</code></pre>
<p>Progressions implement <strong><code>Iterable&lt;N&gt;</code></strong>, where <strong><code>N</code></strong> is <strong><code>Int</code></strong>, <strong><code>Long</code></strong>, or <strong><code>Char</code></strong> respectively, so you can use them in various <a href="https://kotlinlang.org/docs/reference/collection-operations.html">collection functions</a> like <strong><code>map</code></strong>, <strong><code>filter</code></strong>, and other.</p>
<pre><code class="language-kotlin">println( (1..10).filter { it % 2 == 0 } )</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Common patterns when building Room DB]]></title>
            <link>https://velog.io/@dmitry-_-11/Common-patterns-when-building-Room-DB</link>
            <guid>https://velog.io/@dmitry-_-11/Common-patterns-when-building-Room-DB</guid>
            <pubDate>Fri, 22 Jan 2021 10:29:53 GMT</pubDate>
            <description><![CDATA[<h2 id="pattern-1">Pattern 1</h2>
<hr>
<image src="https://images.velog.io/images/dmitry-_-11/post/ab8c4dc8-45fb-4635-8b1e-363191e6643c/image.png" />

<p>Inside  <strong><code>abstract class</code></strong>, <strong><code>private var instance: AppDatabase?</code></strong> with <strong><a href="https://www.baeldung.com/kotlin/volatile-properties">@Volatile</a></strong> keyword.</p>
<h2 id="pattern-2">Pattern 2</h2>
<hr>
<image src="https://images.velog.io/images/dmitry-_-11/post/50a435f7-584a-44c8-95bb-e8d64fa94ba1/image.png" />

<p>Outside <strong><code>abstract class</code></strong>, <strong><code>private lateinit var INSTANCE: TitleDatabase</code></strong>.</p>
<blockquote>
<p><strong>Note</strong>: <strong><code>getDatabase()</code></strong> checks whether <strong><code>INSTANCE</code></strong> has been initialized  during runtime using <strong>property reflection</strong>(<strong><code>::INSTANCE.isInitialized</code></strong>).</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Generics 03 - Wildcards]]></title>
            <link>https://velog.io/@dmitry-_-11/Generics-03-Wildcards</link>
            <guid>https://velog.io/@dmitry-_-11/Generics-03-Wildcards</guid>
            <pubDate>Sun, 17 Jan 2021 09:47:27 GMT</pubDate>
            <description><![CDATA[<p>In generic code, the question mark (?), called the <strong>wildcard</strong>, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific). The wildcard is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype.</p>
<h2 id="upper-bounded-wildcards-link">Upper Bounded Wildcards <a href="https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html">link</a></h2>
<hr>
<p>You can use an upper bounded wildcard to relax the restrictions on a variable. For example, say you want to write a method that works on <code>List&lt;Integer&gt;</code>, <code>List&lt;Double&gt;</code>, and <code>List&lt;Number&gt;</code>; you can achieve this by using an upper bounded wildcard.</p>
<p>To declare an upper-bounded wildcard, use the wildcard character(&#39;<code>?</code>&#39;), followed by the <code>extends</code> keyword, followed by its <em>upper bound</em>. Note that, in this context, extends is used in a general sense to mean either &quot;extends&quot; (as in classes) or &quot;implements&quot; (as in interfaces).</p>
<p>To write the method that works on lists of <code>Number</code> and the subtypes of <code>Number</code>, you would specify <code>List&lt;? extends Number&gt;</code>. The term <code>List&lt;Number&gt;</code>is more restrictive than <code>List&lt;? extends Number&gt;</code> because the former matches a list of type <code>Number</code> only, whereas the latter matches a list of type <code>Number</code> or any of its subclasses.</p>
<p>Consider the following process method:</p>
<pre><code class="language-java">public static void process(List&lt;? extends Foo&gt; list) { /* ... */ }</code></pre>
<p>The upper bounded wildcard , <code>&lt;? extends Foo&gt;</code>, where <code>Foo</code> is any type, matches <code>Foo</code> and any subtype of <code>Foo</code>. The process method can access the listt elements as type <code>Foo</code>:</p>
<pre><code class="language-java">public static void process(List&lt;? extends Foo&gt; list) {
    for (Foo elem: list) {
        // ...    
    }
}</code></pre>
<p>In the foreach clause, the elem variable iterates over each element in the list. Any method defined in the <code>Foo</code> class can now be used on elem.</p>
<p>The <code>sumOfList</code> method returns the sum of the numbers in a list:</p>
<pre><code class="language-java">public static void double sumOfList(List&lt;? extends Number&gt; list) {
    double s = 0.0;
    for (Number n : list)
        s += n.doubleValue();
    return s;
}</code></pre>
<p>The following code, using a list of <code>Integer</code> objects, prints sum = 6.0:</p>
<pre><code class="language-java">List&lt;Integer&gt; li = Arrays.asList(1,2,3);
System.out.println(&quot;sum = &quot; + sumofList(li));</code></pre>
<p>A list of <code>Double</code> values can use the same <code>sumOfList</code> method. The following code prints sum = 7.0:</p>
<pre><code class="language-java">List&lt;Double&gt; ld = Arrays.asList(1.2, 2.3, 3.5);
System.out.println(&quot;sum = &quot; + sumOfList(ld));</code></pre>
<h2 id="unbounded-wildcards-link">Unbounded Wildcards <a href="https://docs.oracle.com/javase/tutorial/java/generics/unboundedWildcards.html">link</a></h2>
<hr>
<p>The unbounded wildcard type is specified using the wildcard character (<code>?</code>), for example, <code>List&lt;?&gt;</code>. This is called <strong>a list of unknown type</strong>. There are two scenarios where an unbounded wildcard is a useful approach:</p>
<ul>
<li><p>If you are writing a method that can be implemented using functionality provided in the <code>Object</code> class.</p>
</li>
<li><p>When the code is using methods in the generic class that don&#39;t depend on the type parameter. For example, <code>List.size</code> or <code>List.clear</code>. In fact, <code>Class&lt;?&gt;</code> is so often used because most of the methods in <code>Class&lt;T&gt;</code> do not depend on <code>T</code>.</p>
</li>
</ul>
<p>Consider the following method, <code>printList</code>:</p>
<pre><code class="language-java">public static void printList(List&lt;Object&gt; list) {
    for (Object elem: list)
            System.out.println(elem + &quot; &quot; ;
    System.out.println();
}</code></pre>
<p>The goal of <code>printList</code> is to print a list of any type, but it fails to achieve that goal - it prints only a list of <code>Object</code> instances; it cannot print <code>List&lt;Integer&gt;</code>, <code>List&lt;String&gt;</code>, <code>List&lt;Double&gt;</code>, and so on, because they are not subtypes of <code>List&lt;Object&gt;</code>. To write a generic <code>printList</code> method, use <code>List&lt;?&gt;</code>:</p>
<pre><code class="language-java">public static void printList(List&lt;?&gt; list) {
    for (Object elem: list)
            System.out.println(elem + &quot; &quot; ;
    System.out.println();
}</code></pre>
<p>Because for any concrete type<code>A</code>, <code>List&lt;A&gt;</code> is a subtype of <code>List&lt;?&gt;</code>, you can use <code>printList</code> to print a list of any type:</p>
<pre><code class="language-java">List&lt;Integer&gt; li = Arrays.asList(1, 2, 3);
List&lt;String&gt;  ls = Arrays.asList(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;);
printList(li);
printList(ls);</code></pre>
<blockquote>
<p><strong>Note</strong> : The <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#asList-T...-">Arrays.asList</a> method is used in examples throughout this lesson. This static factory method converts the specified array and returns a fixed-size list.</p>
</blockquote>
<p>It&#39;s important to note that <code>List&lt;Object&gt;</code> and <code>List&lt;?&gt;</code> are not the same. You can insert an <code>Object</code>, or any subtype of <code>Object</code>, into a <code>List&lt;Object&gt;</code>. But you can only insert <code>null</code> into a <code>List&lt;?&gt;</code>. The <a href="https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html">Guidelines for Wildcard Use</a> section has more information on how to determine what kind of wildcard, if any, should be used in a given situation.</p>
<h2 id="lower-bounded-wildcards-link">Lower Bounded Wildcards <a href="https://docs.oracle.com/javase/tutorial/java/generics/lowerBounded.html">link</a></h2>
<hr>
<p>A <strong>lower bounded</strong> wildcard restricts the unknown type to be a specific type or a <em>super type</em> of that type.</p>
<p>A lower bounded wildcard is expressed using the wildcard character (<code>?</code>), following by the super keyword, followed by its <em>lower bound</em>: <code>&lt;? super A&gt;</code>.</p>
<blockquote>
<p><strong>Note</strong>: You can specify an upper bound for a wildcard, or you can specify a lower bound, but you cannot specify both.</p>
</blockquote>
<p>Say you want to write a method that puts <code>Integer</code> objects into a list. To maximize flexibility, you would like the method to work on <code>List&lt;Integer&gt;</code>, <code>List&lt;Number&gt;</code>, and <code>List&lt;Object&gt;</code> - anything that can hold <code>Integer</code> values.</p>
<p>To write the method that works on lists of <code>Integer</code> and the supertypes of <code>Integer</code>, such as <code>Integer</code>, <code>Number</code>, and <code>Object</code>, you would specify <code>List&lt;? super Integer&gt;</code>. The term <code>List&lt;Integer&gt;</code> is more restrictive than <code>List&lt;? super Integer&gt;</code> because the former matches a list of type <code>Integer</code> only, whereas the latter matches a list of any type that is a supertype of <code>Integer</code>.</p>
<p>The following code adds the numbers 1 throught 10 to the end of a list:</p>
<pre><code class="language-java">public static void addNumbers(List&lt;? super Integer&gt; list) {
    for (int i = 1; i &lt;= 10 ; i++) {
            list.add(i);
       }
}</code></pre>
<p>The <a href="https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html">Guidelines for Wildcard Use</a> section provides guidance on when to use upper bounded wildcards and when to use lower bounded wildcards.</p>
<h2 id="wildcards-and-subtyping-link">Wildcards and Subtyping <a href="https://docs.oracle.com/javase/tutorial/java/generics/subtyping.html">link</a></h2>
<hr>
<p>As described in <a href="">Generics, Inheritance, and Subtypes</a>, generic classes or interfaces are not related merely because there is a relationship between their types. However, you can use wildcards to create a relationship between generic classes or interfaces.</p>
<p>Given the following two regular (non-generic) classes:</p>
<pre><code class="language-java">class A { /* ... */ }
class B extends A { /* ... */ }</code></pre>
<p>It would be reasonalbe to write the following code:</p>
<pre><code class="language-java">B b = new B();
A a = b;</code></pre>
<p>This example shows that inheritance of regular classes follows this rule of subtyping: class B is a subtype of class A if B extends A. This rule does not apply to generic types:</p>
<pre><code class="language-java">List&lt;B&gt; lb = new ArrayList&lt;&gt;();
List&lt;A&gt; la = lb; // compile-time error</code></pre>
<p>Given that <code>Integer</code>  is a subtype of <code>Number</code>, what is the relationship between <code>List&lt;Integer&gt;</code> and <code>List&lt;Number&gt;</code> ?
<img src="https://images.velog.io/images/dmitry-_-11/post/22bd68bc-946a-4b97-ac1c-f0fc140bb8d5/image.png" alt="">
Although <code>Integer</code> is a subtype of <code>Number</code>, <code>List&lt;Integer&gt;</code> is not a subtype of <code>List&lt;Number&gt;</code> and, in fact, these two types are not related. The common parent of <code>List&lt;number&gt;</code> and <code>List&lt;Integer&gt;</code> is <code>List&lt;?&gt;</code>.</p>
<p>In order to create a relationship between these classes so that the code can access <code>Number</code>&#39;s methods through <code>List&lt;inger&gt;</code>&#39;s elements, use an upper bounded whildcard:</p>
<pre><code class="language-java">List&lt;? extends Integer&gt; intList = new ArrayList&lt;&gt;();
List&lt;? extends Number&gt; numList = intList; // OK. List&lt;? extends Integer&gt; is a subtype of List&lt;? extends Number&gt;</code></pre>
<p>Because <code>Intger</code> is a subtype of <code>Number</code>, and <code>numList</code> is a list of <code>Number</code> objects, a relationship now exists between <code>intList</code> (a list of <code>Integer</code> objects) and <code>numList</code>. The following diagram shows the relationships between several <code>List</code> classes declared with bouth upper and lower bounded wildcards.
<img src="https://images.velog.io/images/dmitry-_-11/post/04b55f40-259f-47c9-9f3e-d42d696ec873/image.png" alt="">
The <a href="https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html">Guidelines for Wildcard Use</a> section has more information about the ramifications of using upper and lower bounded wildcards.</p>
<h2 id="wildcard-capture-and-helper-methods">Wildcard Capture and Helper Methods</h2>
<hr>
<p>In some cases, the compiler infers the type of a wildcard. For example, a list may be defined as <code>List&lt;?&gt;</code> but, when evaluating an expression, the compiler infers a particular type from the code. This scenario is known as <em>wildcard capture</em>.</p>
<p>For the most part, you don&#39;t need to worry about wildcard capture, except when you see an error message that contains the phrase &quot;capture of&quot;.</p>
<p>For more information, <a href="https://docs.oracle.com/javase/tutorial/java/generics/capture.html">check this link</a>.</p>
<h2 id="guidelines-for-wildcard-use-link">Guidelines for Wildcard Use <a href="https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html">link</a></h2>
<hr>
<p>One of the more confusing aspects when learning to program with generics is determining when to use an upper bounded wildcard and when to use a lower bounded wildcard. This page provides some guidelines to follow when designing your code.</p>
<p>For purposes of this discussion, it is helpful to think of variables as providing one of two functions:</p>
<p><strong>An &quot;In&quot; Variable</strong></p>
<ul>
<li>An &quot;in&quot; variable serves up data to the code. Imagine a copy method with two arguments: <code>copy(src, dest)</code>. The <code>src</code> argument provides the data to be copied, so it is the <strong>&quot;in&quot;</strong> parameter.</li>
</ul>
<p><strong>An &quot;Out&quot; Variable</strong></p>
<ul>
<li>An &quot;out&quot; variable holds data for use elsewhere. In the copy example, <code>copy(src, dest)</code>, the <code>dest</code> argument accepts data, so it is the <strong>&quot;out&quot;</strong> parameter.</li>
</ul>
<p>You can use the &quot;in&quot; and &quot;out&quot; principle when deciding whether to use a wildcard and what type of wildcard is appropriate. The following list provides the guidelines to follow:</p>
<blockquote>
<p><strong>Wildcard Guidelines:</strong></p>
</blockquote>
<ul>
<li>An <strong>&quot;in&quot;</strong> variable is defined with an upper bounded wildcard, using the <code>extends</code> keyword.</li>
<li>An <strong>&quot;out&quot;</strong> variable is defined with a lower bounded wildcard, using the <code>super</code> keyword.</li>
<li>In the case where the <strong>&quot;in&quot;</strong> variable can be accessed using methods defined in the <code>Object</code> class, use an unbounded wildcard.</li>
<li>In the case where the code needs to access the variable as both an <strong>&quot;in&quot;</strong> and an <strong>&quot;out&quot;</strong> variable, do not use a wildcard. </li>
</ul>
<p>These guidelines do not apply to a method&#39;s return type. Using a wildcard as a return type should be avoided because it forces programmers using the code to deal with wildcards.</p>
<p>A list defined by <code>List&lt;? extends ...&gt;</code> can be informally thought of as read-only, but that is not a strict guarantee. Suppose you have the following two classes:</p>
<pre><code class="language-java">class NaturalNumber {

    private int i;

    public NaturalNumber(int i) { this.i = i; }
    // ...
}

class EvenNumber extends NaturalNumber {

    public EvenNumber(int i) { super(i); }
    // ...
}</code></pre>
<p>Consider the following code:</p>
<pre><code class="language-java">List&lt;EvenNumber&gt; le = new ArrayList&lt;&gt;();
List&lt;? extends NaturalNumber&gt; ln = le;
ln.add(new NaturalNumber(35)); // compile-time error</code></pre>
<p>Because <code>List&lt;EvenNumber&gt;</code> is a subtype of <code>List&lt;? extends NaturalNumber&gt;</code>, you can assign <code>le</code> to <code>ln</code>. But you cannot use <code>ln</code> to add a natural number to a list of even numbers. The following operations on the list are possible:</p>
<ul>
<li>You can add null.</li>
<li>you can invoke clear,</li>
<li>You can get the iterator and invoke remove.</li>
<li>You can capture the wildcard and write elements that you&#39;ve read from the list.</li>
</ul>
<p>you can see that the list defined by <code>List&lt;? extends NaturalNumber&gt;</code> is not read-only in the strictest sense of the word, but you might think of it that way because you cannot store a new element or change an existing element in the list.</p>
<hr>
<h2 id="see-more">See More</h2>
<blockquote>
<p><strong>Type Erasure</strong> <a href="https://docs.oracle.com/javase/tutorial/java/generics/erasure.html">link</a>
<strong>Restrictions on Generics</strong> <a href="https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html">link</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Generics 02 - Bounded Type Parameters and other related topics]]></title>
            <link>https://velog.io/@dmitry-_-11/Generics-02-Bounded-Type-Parameters-and-other-related-topics</link>
            <guid>https://velog.io/@dmitry-_-11/Generics-02-Bounded-Type-Parameters-and-other-related-topics</guid>
            <pubDate>Sat, 16 Jan 2021 15:17:22 GMT</pubDate>
            <description><![CDATA[<h2 id="bound-type-parameters-link">Bound Type Parameters <a href="https://docs.oracle.com/javase/tutorial/java/generics/bounded.html">link</a></h2>
<hr>
<p>There may be times when you want to restrict the types that can be used as type arguments in a parameterized type. For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is what <strong>bounded type parameters</strong> are for.</p>
<p>To declare a bounded type parameter, list the type parameter&#39;s name, followed by the extends keyword, followed by its <strong>upper bound</strong>, which in this example is Number. Note that, in this context, extends is used in a general sense to mean either &quot;extends&quot; (as in classes) or &quot;implements&quot; (as in interfaces).</p>
<pre><code class="language-java">public class Box&lt;T&gt; {

    private T t;          

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }

    public &lt;U extends Number&gt; void inspect(U u){
        System.out.println(&quot;T: &quot; + t.getClass().getName());
        System.out.println(&quot;U: &quot; + u.getClass().getName());
    }

    public static void main(String[] args) {
        Box&lt;Integer&gt; integerBox = new Box&lt;Integer&gt;();
        integerBox.set(new Integer(10));
        integerBox.inspect(&quot;10&quot;); // error: this is still String!
    }
}</code></pre>
<p>By modifying our generic method to include this bounded type parameter, compilation will now fail, since our invocation of inspect still includes a String:</p>
<pre><code>Box.java:21: &lt;U&gt;inspect(U) in Box&lt;java.lang.Integer&gt; cannot
  be applied to (java.lang.String)
                        integerBox.inspect(&quot;10&quot;);
                                  ^
1 error</code></pre><blockquote>
<p>*<em>Result : *</em></p>
</blockquote>
<pre><code class="language-java">public class Box&lt;T&gt; {
  ...
  public &lt;U extends Number&gt; void inspect(U u){
          System.out.println(&quot;T: &quot; + t.getClass().getName());
          System.out.println(&quot;U: &quot; + u.getClass().getName());
  }
  public static void main(String[] args) {
      ...
        Box&lt;Integer&gt; integerBox = new Box&lt;&gt;();
       &gt;    integerBox.set(10);
     integerBox.inspect(0.1); 
        // T: java.lang.Integer
      // U: java.lang.Double
        ...
}</code></pre>
<p>In addition to limiting the types you can use to instantiate a generic type, bounded type parameters allow you to invoke methods defined in the bounds:</p>
<pre><code class="language-java">public class NaturalNumber&lt;T extends Integer&gt; {

    private T n;

    public NaturalNumber(T n)  { this.n = n; }

    public boolean isEven() {
        return n.intValue() % 2 == 0;
    }

    // ...
}</code></pre>
<p>The isEven method invokes the intValue method defined in the Integer class through n.</p>
<h3 id="multiple-bounds">Multiple Bounds</h3>
<p>The preceding example illustrates the use of a type parameter with a single bound, but a type parameter can have <strong>multiple bounds</strong> :    </p>
<pre><code class="language-java">&lt;T extends B1 &amp; B2 &amp; B3&gt;</code></pre>
<p>A type variable with multiple bounds is a subtype of all the types listed in the bound. If one of the bounds is a class, it must be specified first. For example:</p>
<pre><code class="language-java">Class A { /* ... */ }
interface B { /* ... */ }
interface C { /* ... */ }

class D &lt;T extends A &amp; B &amp; C&gt; { /* ... */ }</code></pre>
<p>If bound A is not specified first, you get a compile-time error:</p>
<pre><code class="language-java">class D &lt;T extends B &amp; A &amp; C&gt; { /* ... */ }  // compile-time error</code></pre>
<h2 id="generic-methods-and-bounded-type-parameters-link">Generic Methods and Bounded Type Parameters <a href="https://docs.oracle.com/javase/tutorial/java/generics/boundedTypeParams.html">link</a></h2>
<hr>
<p>Bounded type parameters are key to the implementation of generic algorithms. Consider the following method that counts the number of elements in an array T[] that are greater than a specified element elem.</p>
<pre><code class="language-java">public static &lt;T&gt; int countGreaterThan(T[] anArray, T elem) {
    int count = 0;
    for (T e : anArray)
        if (e &gt; elem)  // compiler error
            ++count;
    return count;
}</code></pre>
<p>The implementation of the method is straightforward, but it does not compile because the greater than operator (&gt;) applies only to primitive types such as short, int, double, long, float, byte, and char. You cannot use the &gt; operator to compare objects. To fix the problem, use a type parameter bounded by the Comparable&lt;T&gt; interface:</p>
<pre><code class="language-java">public interface Comparable&lt;T&gt; {
    public int compareTo(T o);
}</code></pre>
<p>The resulting code will be:</p>
<pre><code class="language-java">public static &lt;T extends Comparable&lt;T&gt;&gt; int countGreaterThan(T[] anArray, T elem) {
    int count = 0;
    for (T e : anArray)
        if (e.compareTo(elem) &gt; 0)
            ++count;
    return count;
}</code></pre>
<h2 id="generics-inheritance-and-subtypes-link">Generics, Inheritance, and Subtypes <a href="https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html">link</a></h2>
<hr>
<p>You can perform a generic type invocation, passing Number as its type argument, and any subsequent invocation of add will be allowed if the argument is compatible with Number:</p>
<pre><code class="language-java">Box&lt;Number&gt; box = new Box&lt;Number&gt;();
box.add(new Integer(10));   // OK
box.add(new Double(10.1));  // OK</code></pre>
<p>Now consider the following method:</p>
<pre><code class="language-java">public void boxTest(Box&lt;Number&gt; n) { /* ... */ }</code></pre>
<p>What type of argument does it accept? By looking at its signature, you can see that it accepts a single argument whose type is Box&lt;Number&gt;. But what does that mean? Are you allowed to pass in Box&lt;Integer&gt; or Box&lt;Double&gt;, as you might expect? The answer is &quot;no&quot;, because Box&lt;Integer&gt; and Box&lt;Double&gt; are not subtypes of Box&lt;Number&gt;.</p>
<p>This is a common misunderstanding when it comes to programming with generics, but it is an important concept to learn.<img src="https://images.velog.io/images/dmitry-_-11/post/4c5f7446-16fe-4ff7-bfca-689ed83ec7a7/image.png" alt=""><center>Box&lt;Integer&gt; is not a subtype of Box&lt;Number&gt; even though Integer is a subtype of Number.</center></p>
<blockquote>
<p><strong>Note:</strong> Given two concrete types A and B (for example, Number and Integer), MyClass&lt;A&gt; has no relationship to MyClass&lt;B&gt;, regardless of whether or not A and B are related. The common parent of MyClass&lt;A&gt; and MyClass&lt;B&gt; is Object.</p>
<p>For information on how to create a subtype-like relationship between two generic classes when the type parameters are related, see <a href="https://docs.oracle.com/javase/tutorial/java/generics/subtyping.html">Wildcards and Subtyping</a>.</p>
</blockquote>
<h3 id="generic-classes-and-subtyping">Generic Classes and Subtyping</h3>
<p>You can subtype a generic class or interface by extending or implementing it. The relationship between the type parameters of one class or interface and the type parameters of another are determined by the extends and implements clauses.</p>
<p>Using the Collections classes as an example, ArrayList&lt;E&gt; implements List&lt;E&gt;, and List&lt;E&gt; extends Collection&lt;E&gt;. So ArrayList&lt;String&gt; is a subtype of List&lt;String&gt;, which is a subtype of Collection&lt;String&gt;. So long as you do not vary the type argument, the subtyping relationship is preserved between the types.
<img src="https://images.velog.io/images/dmitry-_-11/post/d76fde07-bfcb-4cba-a8e9-a5bcd8ad8e2d/image.png" alt=""></p>
<center>A sample Collections hierarchy</center>

<p>Now imagine we want to define our own list interface, PayloadList, that associates an optional value of generic type P with each element. Its declaration might look like:</p>
<pre><code class="language-java">interface PayloadList&lt;E,P&gt; extends List&lt;E&gt; {
  void setPayload(int index, P val);
  ...
}</code></pre>
<p>The following parameterizations of PayloadList are subtypes of List&lt;String&gt;:</p>
<ul>
<li><p>PayloadList&lt;String, String&gt;</p>
</li>
<li><p>PayloadList&lt;String, Integer&gt;</p>
</li>
<li><p>PayloadList&lt;String, Exception&gt;
<img src="https://images.velog.io/images/dmitry-_-11/post/6c972d02-b051-4ee0-b584-9aabce9fb387/image.png" alt=""><center>A sample PayloadList hierarchy</center></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Generics 01 - Generic Types, Generic Methods]]></title>
            <link>https://velog.io/@dmitry-_-11/Generics-01-Generic-Types-Generic-Methods</link>
            <guid>https://velog.io/@dmitry-_-11/Generics-01-Generic-Types-Generic-Methods</guid>
            <pubDate>Sat, 16 Jan 2021 14:44:25 GMT</pubDate>
            <description><![CDATA[<p>Generics add stability to your code by making more of your bugs detectable at compile time.</p>
<h2 id="why-use-generics-link">Why Use generics? <a href="https://docs.oracle.com/javase/tutorial/java/generics/why.html">link</a></h2>
<hr>
<p>In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar <em>formal parameters</em> used in method declarations, type parameters provide a way for you to re-use the same code with different inputs. The difference is that the inputs to formal parameters are values, while the inputs to type parameters are types.</p>
<p>Code that uses generics has many benefits over non-generic code:</p>
<ul>
<li><p>Stronger type checks at compile time.</p>
<p>A Java compiler applies strong type checking to generic code and issues errors if the code violates type safety. Fixing compile-time errors is easier than fixing runtime errors, which can be difficult to find.</p>
</li>
<li><p>Elimination of casts.</p>
<p> The following code snippet without generics requires casting:</p>
<blockquote>
<p>List list = new ArrayList();
list.add(&quot;hello&quot;);
String s = (<strong>String</strong>) list.get(0);</p>
</blockquote>
<p>When re-written to use generics, the code does not require casting:</p>
<blockquote>
<p>List&lt;String&gt; list = new ArrayList&lt;String&gt;();
list.add(&quot;hello&quot;);
String s = list.get(0) // no cast</p>
</blockquote>
</li>
<li><p>Enabling programmers to implement generic algorithms.</p>
<p>By using generics, programmers can implement generic algorithms that work on collections of different types, can be customized, and are type safe and easier to read.</p>
</li>
</ul>
<h2 id="generic-types-link">Generic Types <a href="https://docs.oracle.com/javase/tutorial/java/generics/types.html">link</a></h2>
<hr>
<p>A <strong>generic type</strong> is a generic class or interface that is parameterized over types. The following Box class will be modified to demonstrate the concept.</p>
<h3 id="a-simple-box-class">A Simple Box Class</h3>
<p>Begin by examining a non-generic Box class that operates on objects of any type. It needs only to provide two methods: set, which adds an object to the box, and get, which retrieves it:</p>
<pre><code class="language-java">public class Box {
    private Object object;

    public void set(Object object) { this.object = object; }
    public Object get() { return object; }
}</code></pre>
<p>Since its methods accept or return an Object, you are free to pass in whatever you want, provided that it is not one of the primitive types. There is no way to verify, at compile time, how the class is used. One part of the code may place an Integer in the box and expect to get Integers out of it, while another part of the code may mistakenly pass in a String, resulting in a runtime error.</p>
<h3 id="a-generic-version-of-the-box-class">A Generic Version of the Box Class</h3>
<p>A <strong>generic class</strong> is defined with the following format:</p>
<pre><code class="language-java">class ClassName&lt;T1, T2, .., Tn&gt; { /* ... */ }</code></pre>
<p>The type parameter section, delimited by angle brackets (&lt;&gt;), follows the class name. It specifies the <em>type parameters</em> (also called type variables) T1, T2, ..., and Tn.</p>
<p>To update the Box class to use generics, you create a <em>generic type declaration</em> by changing the code &quot;public class Box&quot; to &quot;public class Box&lt;T&gt;&quot;. This introduces the type variable, T, that can be used anywhere inside the class.</p>
<p>With this change, the Box class becomes:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/c1737edc-34c8-4bbb-a5f9-9024fc1052f5/image.png">
</br>
As you can see, all occurrences of Object are replaced by T. A type variable can be any non-primitive type you specify: any class type, any interface type, any array type, or even another type variable.

<p>This same technique can be applied to create generic interfaces.</p>
<h3 id="invoking-and-instantiating-a-generic-type">Invoking and Instantiating a Generic Type</h3>
<p>To reference the generic Box class from within your code, you must perform a <strong>generic type invocation</strong>, which replaces T with some concrete value, such as Integer:</p>
<pre><code class="language-java">Box&lt;Integer&gt; integerBox = new Box&lt;Integer&gt;();

// In Java SE 7 and later, you can replace the type arguments 
// required to invoke the constructor of a generic class with an empty set of type arguments (&lt;&gt;)
// as long as the compiler can determine, or infer, the type arguments from the context.
// This pair of angle brackets, &lt;&gt;, is informally called the diamond.
Box&lt;String&gt; stringBox = new Box&lt;&gt;(); </code></pre>
<p>You can think of a generic type invocation as being similar to an ordinary method invocation, but instead of passing an argument to a method, you are passing a <strong>type argument</strong> — Integer in this case — to the Box class itself.</p>
<blockquote>
<p>*<em>Type Parameter and Type Argument Terminology : *</em>
Many developers use the terms &quot;type parameter&quot; and &quot;type argument&quot; interchangeably, but these terms are not the same. When coding, one provides type arguments in order to create a parameterized type. Therefore, the T in Foo&lt;T&gt; is a type parameter and the String in Foo&lt;String&gt; f is a type argument.</p>
</blockquote>
<p>An invocation of a generic type is generally known as <strong>parameterized type</strong>.</p>
<h3 id="multiple-type-parameters">Multiple Type Parameters</h3>
<p>As mentioned previously, a generic class can have multiple type parameters. For example, the generic OrderedPair class, which implements the generic Pair interface:</p>
<pre><code class="language-java">public interface Pair&lt;K, V&gt; {
    public K getKey();
    public V getValue();
}

public class OrderedPair&lt;K, V&gt; implements Pair&lt;K, V&gt; {

    private K key;
    private V value;

    public OrderedPair(K key, V value) {
    this.key = key;
    this.value = value;
    }

    public K getKey()    { return key; }
    public V getValue() { return value; }
}</code></pre>
<p>The following statements create two instantiations of the OrderedPair class:</p>
<pre><code class="language-java">Pair&lt;String, Integer&gt; p1 = new OrderedPair&lt;String, Integer&gt;(&quot;Even&quot;, 8);
Pair&lt;String, String&gt;  p2 = new OrderedPair&lt;String, String&gt;(&quot;hello&quot;, &quot;world&quot;);</code></pre>
<p>The code, new OrderedPair&lt;String, Integer&gt;, instantiates K as a String and V as an Integer. Therefore, the parameter types of OrderedPair&#39;s constructor are String and Integer, respectively. Due to <a href="https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html">autoboxing</a>, it is valid to pass a String and an int to the class.</p>
<p>As mentioned in The Diamond, because a Java compiler can infer the K and V types from the declaration OrderedPair&lt;String, Integer&gt;, these statements can be shortened using diamond notation:</p>
<pre><code class="language-java">OrderedPair&lt;String, Integer&gt; p1 = new OrderedPair&lt;&gt;(&quot;Even&quot;, 8);
OrderedPair&lt;String, String&gt;  p2 = new OrderedPair&lt;&gt;(&quot;hello&quot;, &quot;world&quot;);</code></pre>
<p>To create a generic interface, follow the same conventions as for creating a generic class.</p>
<h3 id="parameterized-types">Parameterized Types</h3>
<p>You can also substitute a type parameter (i.e., K or V) with a parameterized type (i.e., List&lt;String&gt;). For example, using the OrderedPair&lt;K, V&gt; example:</p>
<pre><code class="language-java">OrderedPair&lt;String, Box&lt;Integer&gt;&gt; p = new OrderedPair&lt;&gt;(&quot;primes&quot;, new Box&lt;Integer&gt;(...));</code></pre>
<h2 id="raw-types-link">Raw Types <a href="https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html">link</a></h2>
<hr>
<p>A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:</p>
<pre><code class="language-java">public class Box&lt;T&gt; {
    public void set(T t) { /* ... */ }
    // ...
}</code></pre>
<p>To create a parameterized type of Box&lt;T&gt;, you supply an actual type argument for the formal type parameter T:</p>
<pre><code class="language-java">Box&lt;Integer&gt; intBox = new Box&lt;&gt;();</code></pre>
<p>If the actual type argument is omitted, you create a raw type of Box&lt;T&gt;:</p>
<pre><code class="language-java">Box rawBox = new Box();</code></pre>
<p>Therefore, Box is the raw type of the generic type Box&lt;T&gt;. However, a non-generic class or interface type is <em>not</em> a raw type.</p>
<p>More informations are available in <a href="https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html">here</a>.</p>
<h2 id="generic-methods-link">Generic Methods <a href="https://docs.oracle.com/javase/tutorial/java/generics/methods.html">link</a></h2>
<hr>
<p><strong>Generic methods</strong> are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter&#39;s scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.</p>
<p>The syntax for a generic method includes a list of type parameters, inside angle brackets, which appears before the method&#39;s return type. For static generic methods, the type parameter section must appear before the method&#39;s return type.</p>
<p>The Util class includes a generic method, compare, which compares two Pair objects:</p>
<pre><code class="language-java">public class Util {
    public static &lt;K, V&gt; boolean compare(Pair&lt;K, V&gt; p1, Pair&lt;K, V&gt; p2) {
        return p1.getKey().equals(p2.getKey()) &amp;&amp;
               p1.getValue().equals(p2.getValue());
    }
}

public class Pair&lt;K, V&gt; {

    private K key;
    private V value;

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public void setKey(K key) { this.key = key; }
    public void setValue(V value) { this.value = value; }
    public K getKey()   { return key; }
    public V getValue() { return value; }
}</code></pre>
<p>The complete syntax for invoking this method would be:</p>
<pre><code class="language-java">Pair&lt;Integer, String&gt; p1 = new Pair&lt;&gt;(1, &quot;apple&quot;);
Pair&lt;Integer, String&gt; p2 = new Pair&lt;&gt;(2, &quot;pear&quot;);
boolean same = Util.&lt;Integer, String&gt;compare(p1, p2);</code></pre>
<p>The type has been explicitly provided. Generally, this can be left out and the compiler will infer the type that is needed:</p>
<pre><code class="language-java">Pair&lt;Integer, String&gt; p1 = new Pair&lt;&gt;(1, &quot;apple&quot;);
Pair&lt;Integer, String&gt; p2 = new Pair&lt;&gt;(2, &quot;pear&quot;);
boolean same = Util.compare(p1, p2);</code></pre>
<p>This feature, known as <strong>type inference</strong>, allows you to invoke a generic method as an ordinary method, without specifying a type between angle brackets. This topic is further discussed in the following section, <a href="https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html">Type Inference</a>.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Reflection in Kotlin]]></title>
            <link>https://velog.io/@dmitry-_-11/Reflection-in-Kotlin</link>
            <guid>https://velog.io/@dmitry-_-11/Reflection-in-Kotlin</guid>
            <pubDate>Thu, 14 Jan 2021 11:21:37 GMT</pubDate>
            <description><![CDATA[<p>Reflection is a set of language and library features that allows for introspecting the structure of your own program at runtime. Kotlin makes functions and properties first-class citizens in the language, and introspecting them (i.e. learning a name or a type of a property or function at runtime) is closely intertwined with simply using a functional or reactive style.</p>
<h2 id="class-references">Class references</h2>
<hr>
<p>The most basic reflection feature is getting the runtime reference to a Kotlin class. To obtain the reference to a statically known Kotlin class, you can use the class literal syntax:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/0fd43f60-1858-4892-88ee-3e579dd05c47/image.png" />

<p>The reference is value of type <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-class/index.html"><span style="color:#3273e3">KClass</span></a>.</p>
<p>Note that a Kotlin class reference is not the same as a Java class reference. To obtain a Java class reference, use the <code>.java</code> property on a <code>KClass</code> instance.</p>
<blockquote>
<p><strong><a href="https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jvm/runtime/kotlin/jvm/JvmClassMapping.kt">JvmClassMapping.kt</a></strong></p>
<image src="https://images.velog.io/images/dmitry-_-11/post/37c1ea4b-0cb1-4170-81f9-64462c731e6d/image.png">
</blockquote>
<h2 id="bound-class-references-since-11">Bound Class references (since 1.1)</h2>
<hr>
<p>You can get the reference to a class of a specific object with the same <code>::class</code> syntax by using the object as a receiver:</p>
<img src="https://images.velog.io/images/dmitry-_-11/post/c89948f1-f203-4647-879a-49985d022292/image.png">

<h3 id="-in-java--retrieving-class-objects"><a href="https://velog.io/@dmitry-_-11/Reflection">※ In Java</a> <a href="">|</a> <a href="https://docs.oracle.com/javase/tutorial/reflect/class/classNew.html">Retrieving Class Objects</a></h3>
<p>SomeClass.<a href="https://docs.oracle.com/javase/tutorial/reflect/class/classNew.html">class</a>; <span style="color:#a1a1a1">// The .class Syntax</span>
someInstance.<a href="https://docs.oracle.com/javase/tutorial/reflect/class/classNew.html">getClass()</a>; <span style="color:#a1a1a1">// Object.getClass()</span></p>
<h2 id="callable-references">Callable references</h2>
<hr>
<p>References to functions, properties, and constructors, apart from introspecting the program structure, can also be called or used as instances of <a href="https://kotlinlang.org/docs/reference/lambdas.html#function-types"><span style="color:#3273e3">function types</span></a>.</p>
<p>  The common sypertype for all callabel references is <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-callable/index.html"><span style="color:#3273e3">KCallable&lt;out R&gt;</span></a>, where <code>R</code> is </p>
<ul>
<li>the return value type, </li>
<li>which is property type for properties, </li>
<li>and the constructed type for constructors.</li>
</ul>
<h3 id="function-references">Function references</h3>
<p>When we have a named function declared like this:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/b110bdd8-b9b4-44db-91c0-b6737238e7a8/image.png">

<p>We can easily call it directly (<code>isOdd(5)</code>), but we can also use it as a function type value, e.g. pass it to another function. To do this, we use the <code>::</code> operator : </p>
<image src="https://images.velog.io/images/dmitry-_-11/post/62480f17-5d9d-409d-9c17-f11b8173eb62/image.png">

<p>Here <code>::isOdd</code> is  a value of function type <code>(Int) -&gt; Boolean</code>.</p>
<p>Function references belong to one of the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-function/index.html"><span style="color:#3273e3">KFunction&lt;out R&gt;</span></a> subtypes, depending on the parameter count, e.g. <code>KFunction3&lt;T1, T2, T3, R&gt;</code>.</p>
<p><code>::</code> can be used with overloaded functions when the expected type is known from the context. 
For example :</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/461b2f2e-10bc-4253-8546-7f9d4dcb4845/image.png">

<p>Alternatively, you can provide the necessary context by storing the method reference in a variable with an explicitly specified type:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/d17d52de-fe70-4a7d-813e-d8fc7c6d7991/image.png">

<p>If we need to <strong>use a member of a class, or an extension function</strong>, it needs to be qualified, e.g. <code>String::toCharArray</code>.</p>
<p>Note that even if you initialize a variable with a reference to an extension function, the inferred function type will have no <em>receiver</em> (it will have an additional parameter accepting a receiver object). To have a function type with receiver instead, specify the type explicitly:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/760fd8b2-94c5-48cc-ac51-a39670505fa8/image.png">

<blockquote>
<h4 id="receivers"><a href="https://khan.github.io/kotlin-for-python-developers/#receivers">Receivers</a></h4>
<p>The signature of a member function or an extension function begins with a <em>receiver</em> : <strong>the type upon which the function can be invoked</strong>. For example, the signature of <code>toString()</code> is <code>Any.() -&gt; String</code> - it can be called on any non-null object(the receiver), it taks no parameters, and it returns a <code>String</code>. it is possible to write a lambda function with such a signature - this is called a <strong>function literal with receiver</strong>, and is extremely useful for building <a href="https://ko.wikipedia.org/wiki/%EB%8F%84%EB%A9%94%EC%9D%B8_%ED%8A%B9%ED%99%94_%EC%96%B8%EC%96%B4">DSLs</a>.</p>
<p><strong>A function literal with receiver</strong> is perhaps easiest to think of as an extension function in the form of a lambda expression. The declaration looks like an ordinary lambda expression; what makes it take a receiver is the context - it must be passed to a function that takes a function with receiver as a parameter, or assigned to a variable/property whose type is a function type with receiver. The only way to use a function with receiver is to invoke it on an instance of the receiver class, <em>as if it were a member function or extension function</em>. For example:</p>
</blockquote>
<pre><code class="language-kotlin">class Car(val horsepowers: Int)
&gt;
&gt;val boast: Car.() -&gt; String = { I&#39;m a car with $horsepowers HP!&quot; }
&gt;val car = Car(120)
&gt;println(car.boast())</code></pre>
<p>Inside a lambda expression with receiver, you can use <code>this</code> to refer to the receiver object (in this case, <code>car</code>). As usual, you can omit <code>this</code> if there are no naming conflicts, which is why we can simply say <code>$horsepowers</code> instead of <code>${this.horsepowers}</code>. So beware that in Kotlin, <code>this</code> can have different meanings depending on the context: if used inside (possibly nested) lambda expressions with receivers, it refers to the receiver object of the innermost enclosing lambda expression with receiver. If you need to &quot;break out&quot; of the function literal and get the &quot;original&quot; <code>this</code> (the instance the member function you&#39;re inside is executing on), mention the containing class name after <code>this@</code> - so if you&#39;re inside a function literal with receiver inside a member function or Car, use <code>this@Car</code>.</p>
<blockquote>
<p>As with other function literals, if the function takes one parameter (other than receiver object that it is invoked on), the single parameter is implicitly called <code>it</code>, unless you declare another name. If it takes more than one parameter, you must declare their names.</p>
<p>Here&#39;s a small DSL example for constructing tree structures:<img src="https://images.velog.io/images/dmitry-_-11/post/75487d37-f63d-4f25-b0b2-3a0c44bf7c47/image.png" alt="">The block after <code>tree(&quot;weightlifting&quot;)</code> is the first function literal with receiver, which will be passed to <code>tree()</code> as the <code>initialize</code> parameter. According to the parameter list of <code>tree()</code>, the receiver is of type <code>TreeNode</code>, and therefor, <code>tree()</code> can call <code>initialize()</code> on <code>root</code>. <code>root</code> then becomes <code>this</code> insided the scope of that lambda expression, so when we call <code>node(&quot;upper-body&quot;)</code>, it implicitly says <code>this.node(&quot;upper-body&quot;)</code>, where <code>this</code> refers to the same <code>TreeNode</code> as <code>root</code>. The next block is passed to <code>TreeNode.node()</code>, and is invoked on the first child of the <code>root</code> node, namely <code>upper-body</code>, and inside it, <code>this</code> will refer to <code>upper-body</code>.</p>
<p><a href="https://kotlinlang.org/docs/reference/type-safe-builders.html">other example available in here</a></p>
</blockquote>
<h3 id="example-function-composition">Example: function composition</h3>
<p>Consider the following function:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/a8a6107f-6fd1-4934-9c8c-983b24c618a0/image.png">

<p>It reterns a composition of two functions passed to it: <code>compose(f,g) = f(g(*))</code>. Now, you can apply it to callable references:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/f89298a1-4523-444a-bb66-b509e3b9527e/image.png">

<h3 id="property-references">Property references</h3>
<p>To access properties as first-class objects in Kotlin, we can also use the <code>::</code> operator:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/d019c755-9339-4756-bcbf-1fabec2dde09/image.png">

<p>The expression <code>::x</code> evaluates to a property object of type <code>KProperty&lt;Int&gt;</code>, which allows us to read its value using <code>get()</code> or retrieve the property name using the <code>name</code> property. For more information, please refer to the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-property/index.html">docs on the KProperty class</a>. </p>
<p>For a mutable property, e.g. <code>var y = 1</code>, <code>::y</code> returns a value of type <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-mutable-property/">KMutableProperty&lt;Int&gt;</a>, which has a <code>set()</code> method:</p>
<pre><code class="language-kotlin">var y = 1

fun main() {
    ::y.set(2)
    println(y)
}</code></pre>
<p>A property reference can be used where a function with a single generic parameter is expected:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/3a3b6f9c-e542-4c91-b574-b227efb3dae0/image.png">

<image src="https://images.velog.io/images/dmitry-_-11/post/20f5f911-062c-4329-afb1-60e16f195826/image.png">

<p>To access a property that is a member of a class, we qualify it:</p>
<pre><code class="language-kotlin">class A(val p: Int)
val prop = A::p
println(prop.get(A(1)))</code></pre>
<p>For an extension property:</p>
<pre><code class="language-kotlin">val String.lastChar: Char
    get() = this[length - 1]

fun main() {
    println(String::lastChar.get(&quot;abc&quot;))
}</code></pre>
<h3 id="interoperability-with-java-reflection">Interoperability with Java reflection</h3>
<p>On the JVM platform, standard library contains extensions for reflection classes that provide a mapping to and from Java reflection objects (see package <code>kotlin.reflect.jvm</code>). For example, to find a backing field or a Java method that serves as a getter for a Kotlin property, you can say something like this:</p>
<pre><code class="language-kotlin">import kotlin.reflect.jvm.*

class A(val p: Int)

fun main() {
    println(A::p.javaGetter) // prints &quot;public final int A.getP()&quot;
    println(A::p.javaField)  // prints &quot;private final int A.p&quot;
}</code></pre>
<p>To get the Kotlin class corresponding to a Java class, use the <code>.kotlin</code> extension property:</p>
<pre><code class="language-kotlin">fun getKClass(o: Any): KClass&lt;Any&gt; = o.javaClass.kotlin</code></pre>
<h3 id="constructor-references">Constructor references</h3>
<p>Constructors can be referenced just like methods and properties. They can be used wherever an object of function type is expected that takes the same parameters as the constructor and returns an object of the appropriate type. Constructors are referenced by using the <code>::</code> operator and adding the class name. Consider the following function that expects a function parameter with no parameters and return type <code>Foo</code>:</p>
<pre><code class="language-kotlin">class Foo

fun function(factory: () -&gt; Foo) {
    val x: Foo = factory()
}</code></pre>
<p>Using <code>::Foo</code>, the zero-argument constructor of the class Foo, we can simply call it like this:</p>
<pre><code class="language-kotlin">function(::Foo)</code></pre>
<p>Callable references to constructors are typed as one of the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-function/index.html">KFunction&lt;out R&gt;</a> subtypes, denpedning on the parameter count.</p>
<h2 id="bound-function-and-property-references-since-11">Bound function and property references (since 1.1)</h2>
<hr>
<p>You can refer to an instance method of a particular object:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/cae793d4-5e5f-486e-95c0-e6278a354f06/image.png">

<p>Instead of calling the method <code>matches</code> directly we are storing a reference to it. Such reference is bound to its receiver. it can be called directly (like in the example above) or used whenever an expression of function type is expected:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/e2cbe821-a813-4c7f-a14f-0938a9ce4ddc/image.png">

<p>Compare the types of bound and the corresponding unbound references. Bound callable reference has its receiver &quot;attached&quot;  to it, so the type of the receiver is no longer a parameter:
<image src="https://images.velog.io/images/dmitry-_-11/post/8d5c3eea-26b4-4ed6-b9ad-95a696595f81/image.png"></p>
<p>Property referece can be bound as well:
<image src="https://images.velog.io/images/dmitry-_-11/post/f39d4ed6-405e-46be-8013-279d792f8a8a/image.png"></p>
<h3 id="bound-constructor-references">Bound constructor references</h3>
<p>A bound callable reference to a constructor of an <a href="https://kotlinlang.org/docs/reference/nested-classes.html#inner-classes">inner class</a> can be obtained by providing an instance of the outer class:</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/c8048bc3-7f2e-48de-a1c3-401ec828b45b/image.png">]]></description>
        </item>
        <item>
            <title><![CDATA[Reflection - See More]]></title>
            <link>https://velog.io/@dmitry-_-11/Reflection-See-More</link>
            <guid>https://velog.io/@dmitry-_-11/Reflection-See-More</guid>
            <pubDate>Wed, 13 Jan 2021 14:36:21 GMT</pubDate>
            <description><![CDATA[<h2 id="intro">Intro</h2>
<hr>
<p>주변을 자세히 살펴 보자. 이름만 알고 있다면, 그 물체의 모든 정보를 알 수 있는 것들이 많이 존재한다. 내 오른손에 있는 마우스 “MOUSE(MOARUO)”의 경우, 구글과 같은 검색서비스를 이용하면 “Optical, Wheel, Mouse, USB” 라는 정보를 찾아낼 수 있다. 뿐만 아니라, 옥션과 같은 주문서비스를 통해 새로운 “MOUSE(MOARUO)” 마우스를 구매할 수도 있다.</p>
<p>프로그래밍의 세계에서도, 현실의 검색서비스 그리고 주문서비스의 기능을 제공하는데, 이를 “Self Introspection” 또는 “Reflection”이라고 부른다. 클래스(Class)의 이름만으로 클래스의 정보(필드, 메서드)를 찾거나 새로운 객체(Object)를 생성할 수 있다는 얘기다.</p>
<p>Java는 “java.lang.reflect” 패키지를 통해 Reflection 기능을 제공한다. “Java Reflection” 기능은 간접적으로는 알게 모르게 사용하고 있으며, 또한 필요할 경우 직접적으로 사용할 때도 있다. Reflection을 직접적으로 사용할 경우, 항상 성능을 염두해야 하지만, 성능만이 고려대상의 전부는 아니다. 수 차례의 SI 프로젝트를 겪으며 터득한 “Java Reflection”에 대한 진실과 오해에 대해 알아보자.</p>
<h2 id="java-reflection이란">Java Reflection이란?</h2>
<hr>
<p>오늘은 금요일. 마우스를 제어하는 컨트롤러 프로그램을 개발하기 위해 당신은 두 달여 간을 쉬지 않고 일했다. 오늘은 마우스를 호출하는 작업을 완료하면, 두 달 동안 팽개친 애인에게 점수를 딸 수 있는 유일한 기회이다!</p>
<p>여기 2개의 마우스 클래스가 있다. 하나는 유선 마우스로 MouseMoaruo이고, 다른 하나는 MouseMx610으로 무선 마우스다.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/b58ce1fd-bf36-4879-9e46-1db52a24b671/image.png">

<p>  그림 1. 마우스 클래스 Diagram</p>
<p>컨트롤러 프로그램으로부터 받은 마우스 이름을 매개변수로 사용해서, 컨트롤러에 연결할 마우스 클래스의 객체를 생성하는 Factory 클래스를 개발하려고 한다. 매개변수가 “moaruo”일 경우에는 MouseMoaruo 클래스의 객체를 생성하고, “mx610″일 경우에는 MouseMx610 클래스의 객체를 생성해야 한자. 제일 먼저 생각나는 가장 쉬운 접근법은 “if/else”문을 이용하는 것이다</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/de5f0adc-d161-4900-ac51-ea679ef078b7/image.png">
그림 2. if/else문을 이용한 Factory 예


<p>개발이 완료될 즈음, 고객이 표준 마우스 모델이 하나 더 추가 되어야 한다고 수정을 요구했다(여러분이라면 이런 상황은 쉽게 상상할 수 있을 것이다). 늘 그렇듯, 고객의 요구를 받아들여 소스코드를 수정하여 if문을 하나 더 추가하여 요구사항을 해결했다. 이제 퇴근하려는 찰나, 고객은 여러분을 실망시키지 않고 또 다른 마우스를 들고 와서는, 하는 김에 이것도 추가해 달라고 얘기한다. 고객과 애인, 어느 것을 선택할 것 인가!</p>
<p>Factory 클래스의 가장 큰 문제는 if/else문의 사용이다. 객체 지향 프로그램의 대부분에서 if/else문은 필요치 않다. 프로그램에 if/else문(특히, 대량의 if/else문)을 사용했다면, 객체지향 철학을 어긴 것은 아닌지 의심해 보아야 한다.</p>
<p> 애초부터 고객과 애인 중 하나를 선택해야 하는 햄릿의 고민은 할 필요가 없었다. 고객과 애인 모두를 만족시킬 수 있는 방법이 있기 때문이다. Reflection을 사용한 방법이 그것이다.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/41e44f77-1152-4e55-ba19-537ddd0b138a/image.png">
  그림 3. Reflection을 이용한 Factory 예


<p>“그림 3″에서 보는 바와 같이, Constructor 객체를 이용하여 마우스 객체를 생성한다. 이 경우, 컨트롤러에서 클래스의 이름을 넘겨주어야 하지만, 새로운 마우스가 생기더라도 Factory 클래스의 수정 없이 유연하게 확장 가능한 코드가 된 것이다.</p>
<p>우리가 일하는 엔터프라이즈 프로젝트 현장에서는 이와 같은 Reflection이 셀 수 없을 만큼 다양하게 활용하고 있다.</p>
<h2 id="사용처">사용처</h2>
<hr>
<p>현장에서 자바 개발자들이 Reflection을 직접 사용하는 것은 극히 드문 일이다. 그것은 Reflection이 적용될 수 있고 또한 적용되어야 할 곳은 라이브러리 클래스, 공통 컴포넌트 클래스, 그리고 프레임워크와 같이 Reflection을 통해 얻는 이득(재사용성, 확장성, 생산성, 유연성 등)이 극대화될 수 있는 곳이어야 하기 때문이다.</p>
<h3 id="1-java-serialization">1. Java Serialization</h3>
<p>객체를 직렬화(Serialization) 해야 할 경우 Serializable 인터페이스를 구현한다. 그리고, 직렬화된 객체를 읽기 위해서는 java.io.ObjectInputStream 클래스의 readObject() 메서드를 이용한다. 필요에 따라 Serializable 인터페이스를 구현한 클래스가 readObject() 메서드를 구현할 수도 있다. 이때, java.io.ObjectInputStream 클래스의 readObject() 메서드는 내부적으로 Reflection을 이용하여 직렬화된 객체의 readObject() 메서드를 호출한다.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/11e576da-57fa-4418-bfea-1b1088418c24/image.png">
그림 4. Reflection을 사용한 Serialization<br/>

<h3 id="2-apache-commons-beanutils-library">2. Apache Commons BeanUtils library</h3>
<p>Struts 프레임워크를 적용한 프로젝트에서 개발한 경험이 있다면, Apache Commons 프로젝트의 BeanUtils 라이브러리 사용을 고민해 본 경험 또한 있을 것이다. Struts 프레임워크는 HttpRequest 객체의 파라미터를 이용하여 ActionForm 클래스의 객체를 생성한다. 이 ActionForm 클래스의 객체를 생성하는 곳에서도 Reflection이 적용되었다.</p>
<p>Struts를 이용할 경우, 가장 성가신 부분은 ActionForm 클래스의 객체를 대응하는 VO 클래스의 객체로 변환하는 작업이다. 이 작업은 서비스 레이어를 Struts에 종속되지 않게 하기 위해 또는, 레이어 분리를 위해 반드시 수행되어야 한다. 만일 지금까지 ActionForm 객체를 서비스 레이어로 바로 넘겼다면 다시 한번 생각해 보라. VO 클래스 사용에 따른 레이어의 분리와, VO를 사용하지 않음으로써 얻는 개발 생산성 증가, 둘 중 어느 한가지를 택한 것인지.</p>
<p>이때, 사용할 수 있는 것이 Commons BeanUtils 라이브러리이다. Beanutils.copyProperties(Object dest, Object orig)를 이용하여 간단히 ActionForm 객체를 VO 객체로 변환할 수 있다. 규칙은 ActionForm 클래스의 인스턴스 변수명과 VO 클래스의 인스턴수 변수명이 같아야 한다는 것이다. 이 규칙을 따른다면, Reflection의 마술이 여러분을 위한 모든 작업을 수행해 줄 것이다. </p>
<h2 id="이슈">이슈</h2>
<hr>
<h3 id="1-reflection을-사용한-코드는-느리다">1. Reflection을 사용한 코드는 느리다</h3>
<p>개발자들 사이에 공공연히 진실로 받아들여지는 이 말은 사실이 아니다. 적절히 사용한 Reflection은 오히려 성능을 향상시킬 수 있으며, 또한 많은 이득을 제공한다. 뿐만 아니라, 성능만을 고려한 구현이 객체 지향의 설계 원칙들을 역행한다면, 오히려 이는 더욱 나쁜 결과를 낳게 된다.</p>
<h3 id="2-reflection을-이용하여-개발한-프로그램은-에러가-발생하기-쉽고-디버깅이-어렵다">2. Reflection을 이용하여 개발한 프로그램은 에러가 발생하기 쉽고 디버깅이 어렵다</h3>
<p>Reflection은 컴파일 시 타입 체킹을 할 수 없다. 따라서, 런타임시 잘못된 파라미터로 인해 런타임 에러가 발생하기 쉽다. 이는 사실이다. 하지만, 적절히 사용된 런타임 에러 메시지를 이용해 충분히 디버깅이 쉬운 환경으로 만들 수 있다.</p>
<h3 id="3-reflection을-사용한-코드는-복잡하다">3. Reflection을 사용한 코드는 복잡하다</h3>
<p>Reflection을 사용한 코드는 일반적인 객체 생성, 메서드 호출 코드에 비교하면 복잡한 것이 사실이다. 하지만 클래스의 타입을 비교하여 객체를 생성하는 코드의 경우, 대량의 if/else문을 사용하는 것보다 Reflection을 이용하여 재사용 가능한 컴포넌트로 만든다면, 오히려 코드를 단순화한다.</p>
<h3 id="4-성능performance-vs-유연성flexibility">4. 성능(Performance) vs. 유연성(Flexibility)</h3>
<p>앞서 말한 바와 같이 “Reflection을 사용한 코드는 느리다”는 사실은 사실이 아니다. 이 말은 Reflection을 사용할 경우 성능이 떨어지지 않는다라는 얘기가 아니다. 오히려, 성능이 떨어진다는 결과가 다수 존재한다. 아래는 Dennis Sosnoski(5. Java Programming dynamics, Part 2: Introducing reflection)가 측정한 Reflection에 관한 성능 결과이다. 그림에서 알 수 있듯이, Reflection을 사용할 경우, 직접(Direct) 또는 참조(Reference)의 경우에 비해 2 ~ 4배 정도 느리다.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/91a93e78-bb5d-486c-a77f-cfa6473fd770/image.png">
그림 5. 필드 변수 Access 시간




<image src="https://images.velog.io/images/dmitry-_-11/post/bdac740c-3958-47cf-8f8f-d4ff8e5c3356/image.png">
그림 6. 메서드 호출 시간


<p>이 결과를 통해 알 수 있는 사실은 “Reflection에 따른 성능 저하”가 아니라 “성능 측정 결과, Reflection을 사용한 <strong>지금 이 경우에는</strong> 성능이 저하되는 것을 검증했다”라는 것이다. 최적화 또는 성능 개선(Optimization)시 유의해야 할 점은 반드시 최적화 이전과 이후의 성능을 측정하여, 성능개선이 가시적으로 보일 때에만 적용해야 한다는 것이다. 만일 최적화가 필요하다고 느낀다면, 아래 규칙을 따르라.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/467d3a4b-002c-44b6-bf24-caa139057e8d/image.png">
그림 7. 최적화 규칙


<p>Reflection과 관련된 성능에 관한 논쟁은 오해에서 비롯된 것이다. 이것은 JDK 초기 버전(1.3.0 이전 버전)의 경우 Reflection의 성능이 현저히 떨어졌다. 하지만 이후의 JDK 버전에서는, Reflection의 중요성을 인식한 Sun의 지속적인 노력으로 성능이 개선되고 있으며, 앞으로도 개선의 여지가 남아 있다. 뿐만 아니라 잘 적용한 Reflection은 많은 이득을 제공한다.</p>
<p>Reflection을 통해 얻을 수 있는 가장 큰 이득은 시스템 유연성(Flexibility)이다. “그림 3″에서 보는 바와 같이 Mouse 컨트롤러는 미래의 어떤 마우스와도 동작할 수 있다. 이처럼 성능보다 유연성이 더 중요한 상황이 많다</p>
<p>물론 Reflection 적용에 따른 가시적인 성능 저하를 확신한다면, 다른 대안을 생각해 볼 수 있다. 대안에는, Reflection 대신 interface를 통한 메서드 호출, 코드 자동 생성(Code Generation), 또는 최악의 경우 하드 코딩이 있다.</p>
<h3 id="5-compile-vs-run-time-type-checking">5. Compile vs. Run-time Type Checking</h3>
<p> 자바의 경우 컴파일 단계에 강력한 Type Checking을 지원한다. 아래와 같이 두 개의 클래스가 틀릴 경우, 컴파일이 에러가 발생한다.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/65a3a0a3-b53c-47ee-82b6-693689cc0f90/image.png">

<p>그림 8. 컴파일 에러 예</p>
<p>Reflection은 실제 클래스 없이 클래스의 이름 또는 메서드의 이름만을 이용한다. 따라서, 아래와 같이, 개발 단계 또는 컴파일 단계에는 Type Checking을 하지 않는다.</p>
<image src="https://images.velog.io/images/dmitry-_-11/post/2ff47a26-a6ed-4beb-9186-f2ef22f1e78e/image.png">
그림 9. Checked Exception 예


<p>대신, 실행시 발생할 수 있는 Exception을 처리하기 위한 try/catch문을 추가해야 한다.</p>
<p>자바가 제공하는 Exception의 종류에는 Checked Exception, Run-time Exception 그리고 error가 있다. 이중 Checked Exception의 경우, 위와 같이 컴파일 단계에 catch하거나 throw해야만 컴파일 오류가 발생하지 않는다. 이는 Checked Exception은 예외 상황에서 프로그램적으로 복구할 수 있는 방법이 존재하는 경우를 위한 Exception이기 때문이다.</p>
<p>하지만 Reflection 사용에 따른 Exception으로부터 복구할 수 있는 상황이란 거의 없다. 예를 들어, 위의 Class Not Found Exception이 발생한다면, 이는 클라이언트가 잘못된 클래스 명을 넘겨주었거나 또는 해당 클래스가 없을 2가지 경우다. 이는 모두 프로그램 에러 상황으로 오히려 Run-time Exception에 가깝다.</p>
<p> 결국, Reflection을 사용함으로써, 개발단계에서 조기에 발견될 수도 있었을 프로그램 에러들이 런타임시에 발생하게 되는 것이다. 이처럼 에러 상황이 늦게 발견하면 디버깅이 어려워지게 된다. 이와 같은 경우를 위해서, 런타임시 디버깅을 위해 상세한 에러 메시징 기능을 포함하는 것이 좋다.</p>
<h2 id="drug-heals-the-pain-overdose-kills-the-gain">Drug heals the pain, Overdose kills the gain</h2>
<hr>
<p>  Reflection의 사용에 관한 사실들은 사실 사실이 아니다. 성능, 디버깅, 그리고 복잡성과 관련된 내용들은 잘못 사용된 예에서 파생한 오해들이다.</p>
<p>Reflection은 염려할 만큼의 성능저하를 가져오지 않는다. 대량의 if/else문이나 switch문 대신, 잘 설계된 Reflection은 객체지향 철학을 어기지 않으면서도 더 좋은 성능을 발휘할 수도 있다.</p>
<p>또한 디버깅이 어려운 것은 컴파일 단계에 처리할 수 있는 오류들이 실행 단계에 발생하기 때문이 아니다. 더 근본적인 이유는 Reflection을 사용할 경우에 발생할 런타임 에러 메시지를 최대한 상세하게 그리고 친절하게 표시하도록 Exception 전략을 설계하지 못했기 때문이다. 잘 설계된 Exception 처리 전략은 Reflection 뿐만 아니라 시스템의 전체적인 디버깅을 쉽게 만든다.</p>
<p>Reflection의 복잡성은 사실 개발자 개개인의 초점에 맞추었을 때의 얘기다. 하지만, Reflection의 사용은 개발자의 관점이 아닌 아키텍트 중심으로 설계되어야 한다. Reflection이 가장 유용한 곳이 바로 시스템의 아키텍처를 이루는 컴포넌트들이기 때문이다. 오히려 잘 설계된 Reflection이 제공하는 서비스는 개발을 더욱 단순화 한다.</p>
<p>하지만 지나친 사용은 화를 부를 수 있다. Reflection을 적절히 사용했고 많은 이득이 따른다 하더라도, 더 간단한 해결책이 존재한다면, Reflection을 사용하지 말 것을 권한다. 단순한 해결책은 언제 어느 경우에나 최상의 선택이다.</p>
<p>Reflection의 사용은 양날의 검과 같다. 잘 사용한다면, 이름을 불러주었을 때, 여러분의 꽃이 되어 줄 것이다.</p>
<h2 id="references-">References :</h2>
<blockquote>
<p><a href="https://kmongcom.wordpress.com/2014/03/15/%EC%9E%90%EB%B0%94-%EB%A6%AC%ED%94%8C%EB%A0%89%EC%85%98%EC%97%90-%EB%8C%80%ED%95%9C-%EC%98%A4%ED%95%B4%EC%99%80-%EC%A7%84%EC%8B%A4/">본문 | 자바 리플렉션에 대한 오해와 진실</a>
  <a href="https://www.ibm.com/developerworks/java/library/j-dyn0429/">Java Programming dynamics, Part1: Java classes and class loading</a> 
 <a href="https://www.ibm.com/developerworks/library/j-dyn0603/">Java Programming dynamics, Part2: Introducing reflection</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Reflection]]></title>
            <link>https://velog.io/@dmitry-_-11/Reflection</link>
            <guid>https://velog.io/@dmitry-_-11/Reflection</guid>
            <pubDate>Wed, 13 Jan 2021 12:48:08 GMT</pubDate>
            <description><![CDATA[<h2 id="what-is-reflection-">What is Reflection ?</h2>
<hr>
<p>리플렉션(Reflection)은 : </p>
<ul>
<li><p>객체를 통해 클래스의 정보를 분석해내는 프로그램 기법이다.</p>
</li>
<li><p>클래스 파일의 위치나 이름만 있으면 해당 클래스의 정보를 얻어내고, 객체를 생성하는 것 또한 가능하게 해주는 유연한 프로그래밍을 위한 기법이다. 동적으로 객체를 생성하는 것 또한 가능하다.</p>
</li>
<li><p>Class 클래스</p>
<ul>
<li>Java 에서 사용되는 클래스들에 대한 구조에 관한 정보를 가지고 있는 클래스.</li>
<li><img src="https://images.velog.io/images/dmitry-_-11/post/16f30428-ac9f-4ef7-ac1c-b930a2da28e3/image.png" alt=""></li>
<li>User 클래스는 4개의 필드, 2개의 생성자, 9개의  메소드(getter/setter 포함)라는 속성을 가지고 있는 클래스로 정의 된다.</li>
<li>클래스라는 것 자체도 필드, 생성자, 메소드 등과 같은 <strong>속성</strong>을 가지고 있다고 생각 할 수 있다.</li>
<li>즉, Class 클래스는 이러한 <strong>클래스의 구조 자체를 하나의 클래스로 표현해놓은 클래스</strong> 이다.</li>
</ul>
</li>
</ul>
<h2 id="example">Example</h2>
<hr>
<h3 id="class-reflection">Class Reflection</h3>
<pre><code class="language-java">package kr.klokov.Reflection;

import java.util.ArrayList;
import java.util.HashSet;

public class ClassReflection {

    private static void getClassHelper(Object o) {
        System.out.println(o.getClass());
    }

    private static void dotClassHelper(Class c) {
        System.out.println(c);
    }

    public static void main(String[] args) {

        // getClass()
        getClassHelper(&quot;string&quot;); // class java.lang.String
        getClassHelper(new HashSet()); // class java.util.HashSet
        getClassHelper(new byte[1024]); // class [B
        getClassHelper(new ArrayList&lt;String&gt;()); // class java.util.ArrayList

        // .class
        dotClassHelper(boolean.class); // boolean
        dotClassHelper(java.io.File.class); // class java.io.File
    }
}
</code></pre>
<h3 id="field-reflection">Field Reflection</h3>
<pre><code class="language-java">package kr.klokov.Reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class FieldReflection {

    public static final int a = 10;
    private double b;
    protected static final String s = &quot;hello!&quot;;

    public static void main(String[] args) {
        try {
            Class c = Class.forName(&quot;kr.klokov.Reflection.FieldReflection&quot;);
            Field[] fields = c.getDeclaredFields();

            for(int i = 0; i &lt; fields.length ; i++) {

                System.out.println(&quot;---------------------------&quot;);

                Field field = fields[i];

                System.out.println(&quot;name : &quot; + field.getName());
                System.out.println(&quot;declare Class : &quot; + field.getDeclaringClass());
                System.out.println(&quot;type : &quot; + field.getType());
                System.out.println(&quot;modifier : &quot; + Modifier.toString(field.getModifiers()));

            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
</code></pre>
<h3 id="method-reflection">Method Reflection</h3>
<pre><code class="language-java">package kr.klokov.Reflection;

import java.lang.reflect.Method;

public class MethodReflection {
    public int sum(int a, int b) throws NoSuchFieldException {
        return a+b;
    }

    public static void main(String[] args) {
        try {
            Class c = Class.forName(&quot;kr.klokov.Reflection.MethodReflection&quot;);

            Method[] m = c.getDeclaredMethods();

            for (int i = 0 ; i &lt; m.length ; i++) {
                System.out.println(&quot;--------------------------------&quot;);
                Method method = m[i];
                System.out.println(&quot;name : &quot; + method.getName());
                System.out.println(&quot;declare Class : &quot; + method.getDeclaringClass());

                Class[] parameterTypes = method.getParameterTypes();
                for (int j = 0; j &lt; parameterTypes.length ; j++) {
                    System.out.println(&quot;Param : &quot; + parameterTypes[j]);
                }

                Class[] exceptionTypes = method.getExceptionTypes();
                for (int j = 0; j &lt; exceptionTypes.length ; j++) {
                    System.out.println(&quot;Exception : &quot; + exceptionTypes[j]);
                }

                System.out.println(&quot;Return Type : &quot; + method.getReturnType());

            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
 }
</code></pre>
<h3 id="constructor-reflection">Constructor Reflection</h3>
<pre><code class="language-java">package kr.klokov.Reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

public class ConstructorReflection {

    public ConstructorReflection() {}

    protected ConstructorReflection(String s, int b) {}

    private ConstructorReflection(String s, int b, int c) {}

    ConstructorReflection(String a, int b, char c) {}

    public static void main(String[] args) {
        try {
            Class c = Class.forName(&quot;kr.klokov.Reflection.ConstructorReflection&quot;);

            Constructor[] constructors = c.getDeclaredConstructors();

            for (int i = 0 ; i &lt; constructors.length ; i++) {
                System.out.println(&quot;---------------------------------&quot;);
                Constructor constructor = constructors[i];
                System.out.println(&quot;name : &quot; + constructor.getName());
                System.out.println(&quot;declare Class : &quot; + constructor.getDeclaringClass());
                System.out.println(&quot;modifier : &quot; + Modifier.toString(constructor.getModifiers()));

                Class[] parameterTypes = constructor.getParameterTypes();

                for (int j = 0 ; j &lt; parameterTypes.length ; j++) {
                    System.out.println(&quot;Params : &quot; + parameterTypes[j]);
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}</code></pre>
<h2 id="more-other-post-available-in-here">More (<a href="https://velog.io/@dmitry-_-11/Reflection-See-More">Other post available in HERE</a>)</h2>
<hr>
<blockquote>
</blockquote>
<h3 id="1-the-reflection-api--java-doc"><a href="https://docs.oracle.com/javase/tutorial/reflect/index.html">1. The Reflection API | Java Doc</a></h3>
<h3 id="2-자바-reflection-이란"><a href="https://medium.com/msolo021015/%EC%9E%90%EB%B0%94-reflection%EC%9D%B4%EB%9E%80-ee71caf7eec5">2. 자바 Reflection 이란?</a></h3>
<h3 id="3-java-reflection-개념-및-사용법"><a href="https://gyrfalcon.tistory.com/entry/Java-Reflection">3. Java Reflection 개념 및 사용법</a></h3>
<h3 id="4-reflection-class-클래스"><a href="https://joont.tistory.com/165">4. Reflection, Class 클래스</a></h3>
<h3 id="5-string-in-java--journaldev"><a href="https://www.journaldev.com/797/what-is-java-string-pool">5. String in Java | JournalDev</a></h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[Static]]></title>
            <link>https://velog.io/@dmitry-_-11/Static</link>
            <guid>https://velog.io/@dmitry-_-11/Static</guid>
            <pubDate>Mon, 11 Jan 2021 10:54:15 GMT</pubDate>
            <description><![CDATA[<h2 id="static-variable">Static variable</h2>
<hr>
<blockquote>
<h3 id="compare">Compare</h3>
</blockquote>
<pre><code class="language-java">public class HousePark  {
    String lastname = &quot;Park&quot;;
&gt;
    public static void main(String[] args) {
        HousePark pey = new HousePark();
        HousePark pes = new HousePark();
    }
}</code></pre>
<blockquote>
<pre><code class="language-java">public class HousePark  {
    static String lastname = &quot;Park&quot;;
</code></pre>
</blockquote>
<pre><code>public static void main(String[] args) {
    HousePark pey = new HousePark();
    HousePark pes = new HousePark();
}</code></pre><pre><code>
위와 같이 `lastname` 변수에 &lt;span style=&quot;color:#ff00ff&quot;&gt;static&lt;/span&gt; 키워드를 붙이면 자바는 메모리 할당을 딱 한번만 하게 되어 메모리 사용에 이점을 볼 수 있게된다.

&lt;span style=&quot;color:#808080&quot;&gt;
※ 만약 HousePark 클래스의 lastname값이 변경되지 않기를 바란다면 static 키워드 앞에 final이라는 키워드를 붙이면 된다. final 키워드는 한번 설정되면 그 값을 변경하지 못하게 하는 기능이 있다. 변경하려고 하면 예외가 발생한다.
&lt;/span&gt;


&gt; ### Compare
&gt;#### Example 1 : Code
```java
public class Counter  {
    int count = 0;
    Counter() {
        this.count++;
        System.out.println(this.count);
    }
&gt;
    public static void main(String[] args) {
        Counter c1 = new Counter();
        Counter c2 = new Counter();
    }
}</code></pre><blockquote>
<h4 id="example-1--result">Example 1 : Result</h4>
</blockquote>
<pre><code class="language-java">1
1</code></pre>
<blockquote>
<br>


<h4 id="example-2--code">Example 2 : Code</h4>
<pre><code class="language-java">public class Counter  {
    static int count = 0;
    Counter() {
        this.count++;
        System.out.println(this.count);
    }
</code></pre>
</blockquote>
<pre><code>public static void main(String[] args) {
    Counter c1 = new Counter();
    Counter c2 = new Counter();
}</code></pre><p>}</p>
<pre><code>&gt;#### Example 2 : Result
&gt;```java
1
2</code></pre><p><strong>Example 1</strong> 
 c1, c2 객체 생성시 count 값을 1씩 증가하더라도 c1과 c2의 count는 서로 다른 메모리를 가리키고 있기 때문에 원하던 결과(카운트가 증가된)가 나오지 않는 것이다. 객체변수는 항상 독립적인 값을 갖기 때문에 당연한 결과이다.</p>
<p> <strong>Example 2</strong>
 <code>int count = 0</code> 앞에 static 키워드를 붙였더니 count 값이 공유되어 다음과 같이 방문자수가 증가된 결과값이 나오게 되었다.</p>
<h2 id="static-method">Static Method</h2>
<hr>
<blockquote>
<h3 id="example">Example</h3>
</blockquote>
<pre><code class="language-java"> public class Counter  {
    static int count = 0;
    Counter() {
        this.count++;
    }
&gt;
    public static int getCount() {
        return count;
    }
&gt;
    public static void main(String[] args) {
        Counter c1 = new Counter();
        Counter c2 = new Counter();
&gt;
        System.out.println(Counter.getCount());
    }
}</code></pre>
<p> <code>getCount()</code> 라는 static 메소드가 추가되었다. <code>main</code> 에서 <code>getCount()</code>는 <code>Counter.getCount()</code> 와 같이 클래스를 통해 호출할 수 있게 된다.</p>
 <span style="color:#808080">
  ※ 스태틱 메소드 안에서는 인스턴스 변수 접근이 불가능 하다. 위 예에서 count는 static 변수이기 때문에 스태틱 메소드(static method)에서 접근이 가능한 것이다.
  </span>]]></description>
        </item>
        <item>
            <title><![CDATA[Access Modifier]]></title>
            <link>https://velog.io/@dmitry-_-11/Access-Modifier</link>
            <guid>https://velog.io/@dmitry-_-11/Access-Modifier</guid>
            <pubDate>Mon, 11 Jan 2021 10:39:40 GMT</pubDate>
            <description><![CDATA[<h2 id="overview">Overview</h2>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/16d6b033-a474-4e51-ba67-25a0c561f33f/image.png" alt="">
자바에는 다음과 같은 접근 제어자가 있다.</p>
<ol>
<li>private</li>
<li>default</li>
<li>protected</li>
<li>public</li>
</ol>
<p>private → default → protected → public 순으로 보다 많은 접근을 허용한다.</p>
<h2 id="private">private</h2>
<hr>
<p>private이 붙은 변수, 메소드는</p>
<ul>
<li>해당 클래스에서만 접근이 가능하다.</li>
</ul>
<blockquote>
<h3 id="example">Example</h3>
</blockquote>
<pre><code class="language-java">public class AccessModifier {
    private String secret;
    private String getSecret() {
        return this.secret;
    }
}</code></pre>
<blockquote>
<p>위 예제의 <code>secret</code> 변수와  <code>getSecret()</code> 메소드는 오직 <code>AccessModifier</code> 클래스에서만 접근이 가능하다.</p>
</blockquote>
<h2 id="default">default</h2>
<hr>
<p>접근 제어자를 별도로 설정하지 않는다면, 접근 제어자가 없는 변수, 메소드는</p>
<ul>
<li>default 접근제어자가 되어 해당 패키지 내에서만 접근이 가능하다.</li>
</ul>
<blockquote>
<h3 id="example-1">Example</h3>
</blockquote>
<pre><code class="language-java">package jump2java.house;
&gt;
public class HouseKim {
    String lastname = &quot;kim&quot;;
}</code></pre>
<blockquote>
<pre><code class="language-java">package jump2java.house;
</code></pre>
</blockquote>
<p>public class HousePark {
    String lastname = &quot;park&quot;;</p>
<blockquote>
</blockquote>
<pre><code>public static void main(String[] args) {
    HouseKim kim = new HouseKim();
    System.out.println(kim.lastname);
}</code></pre><p>}</p>
<pre><code>`HouseKim`과 `HousePark`의 패키지는 **jump2java.house** 로 동일하다. `HouseKim` 클래스의 `lastname` 변수는 접근제어자가 default 이므로 `HousePark` 클래스에서 `main` 메소드에서 사용한 것과 같이 `kim.lastname` 으로 `HouseKim` 의 `lastname` 변수에 접근이 가능하다.


## protected
---
접근 제어자가 protected로 설정되었다면, protected가 붙은 변수, 메소드는
- 동일 패키지내의 클래스 또는
- 해당 클래스를 상속받은 외부 패키지의 클래스

에서 접근이 가능하다.

&gt; ### Example
```java
package jump2java.house;
&gt;
public class HousePark {
    protected String lastname = &quot;park&quot;;
}</code></pre><blockquote>
<pre><code class="language-java">package jump2java.house.person;
</code></pre>
</blockquote>
<p>import house.HousePark;</p>
<blockquote>
</blockquote>
<p>public class EungYongPark extends HousePark {<br>    public static void main(String[] args) {
        EungYongPark eyp = new EungYongPark();
        System.out.println(eyp.lastname);<br>    }<br>}</p>
<pre><code>`HousePark` 클래스를 상속받은 `EungYongPark`이라는 클래스의 패키지는 **jump2java.house.person**으로 `HousePark`의 패키지인 **jump2java.house**와 다르지만 `HousePark`의 `lastname` 변수가 `protected`로 설정되었기 때문에 `eyp.lastname`과 같은 접근이 가능하다.
&gt;
만약 `lastname`의 접근제어자가 protected 가 아닌 default 접근제어자였다면 `eyp.lastname` 문장은 컴파일 에러를 유발 할 것이다.


## public
---
접근 제어자가 public으로 설정되었다면 public 접근 제어자가 붙은 변수, 메소드는
- **어떤 클래스에서라도 접근이 가능하다.**

&gt; ### Example
```java
package jump2java.house;
&gt;
public class HousePark {
    protected String lastname = &quot;park&quot;;
    public String info = &quot;this is public message.&quot;;
}</code></pre><p>위 예제의 <code>HousePark</code>의 <code>info</code> 변수는 public 접근제어자가 붙어 있으므로 어떤 클래스에서던지 접근이 가능하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Abstraction]]></title>
            <link>https://velog.io/@dmitry-_-11/Abstraction</link>
            <guid>https://velog.io/@dmitry-_-11/Abstraction</guid>
            <pubDate>Mon, 11 Jan 2021 10:17:54 GMT</pubDate>
            <description><![CDATA[<h2 id="abstract-classes-and-methods">Abstract Classes and Methods</h2>
<p>Data <strong>abstraction</strong> is the process of hiding certain details and showing only essential information to the user. Abstraction can be achieved with either <strong>abstract classes</strong> or <a href="https://velog.io/@dmitry-_-11/Interface"><strong>interfaces</strong></a></p>
<p>The <span style="color:#ff00ff">abstract</span> keyword is <strong>non-access modifier</strong>, used for classes and methods:</p>
<ul>
<li><p>*<em>Abstract class: *</em> is a restricted class that cannot be used to create objects (to access it, it must be inherited from another class).</p>
</li>
<li><p><strong>Abstract method:</strong> can only be used in an abstract class, and it does not have a body. The body is provided by the subclass (inherited from).</p>
</li>
</ul>
<p>An abstract class can have both abstract and regular methods:</p>
<blockquote>
<pre><code class="language-java">abstract class Animal {
  public abstract void animalSound();
  public void sleep() {
    System.out.println(&quot;Zzz&quot;);
  }
}</code></pre>
</blockquote>
<pre><code>
From the example above, it is not possible to create an object of the Animal class:
&gt;```java
Animal myObj = new Animal(); // will generate an error</code></pre><p>To access the abstract class, it must be inherited from another class. </p>
<blockquote>
<h3 id="example">Example</h3>
</blockquote>
<pre><code class="language-java">// Abstract class
abstract class Animal {
  // Abstract method (does not have a body)
  public abstract void animalSound();
  // Regular method
  public void sleep() {
    System.out.println(&quot;Zzz&quot;);
  }
}
&gt;
// Subclass (inherit from Animal)
class Pig extends Animal {
  public void animalSound() {
    // The body of animalSound() is provided here
    System.out.println(&quot;The pig says: wee wee&quot;);
  }
}
&gt;
class Main {
  public static void main(String[] args) {
    Pig myPig = new Pig(); // Create a Pig object
    myPig.animalSound();
    myPig.sleep();
  }
}</code></pre>
<h2 id="see-more">See More</h2>
<p><a href="https://johngrib.github.io/wiki/java-abstract-class/">Java Abstract Class</a>
<a href="https://www.w3schools.com/java/java_abstract.asp">Java Abstraction</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Polymorphism]]></title>
            <link>https://velog.io/@dmitry-_-11/polymorphism</link>
            <guid>https://velog.io/@dmitry-_-11/polymorphism</guid>
            <pubDate>Mon, 11 Jan 2021 10:06:52 GMT</pubDate>
            <description><![CDATA[<h2 id="usage">Usage</h2>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/78faa66c-0fd0-4d6e-925c-ba49f501ddcd/image.png" alt=""><img src="https://images.velog.io/images/dmitry-_-11/post/2b5edca7-27f3-44d7-bee8-a703ded5d307/image.png" alt=""><img src="https://images.velog.io/images/dmitry-_-11/post/5aa94a24-9ccc-4c56-ae00-48be6d894ed2/image.png" alt=""><img src="https://images.velog.io/images/dmitry-_-11/post/23653faf-8729-4823-90fc-7852cde487c0/image.png" alt=""><img src="https://images.velog.io/images/dmitry-_-11/post/bebe89f1-4fdb-45db-8391-3c507b51bff6/image.png" alt=""></p>
<h2 id="what-is-polymorphism">What is Polymorphism?</h2>
<p>tiger, lion 객체는 각각 :</p>
<ul>
<li><p>Tiger, Lion 클래스의 객체이면서, </p>
</li>
<li><p>Animal 클래스의 객체이기도 하고,</p>
</li>
<li><p>Barakble, Predator 인터페이스의 객체이기도 하다.</p>
</li>
</ul>
<p>이러한 이유로 <code>barkAnimal</code>메소드의 입력 자료형을 <code>Animal</code>에서 <code>Barkable</code>로 바꾸어 사용할 수 있는 것이다.</p>
<p>이렇게 하나의 객체가 여러개의 자료형 타입을 가질 수 있는 것을 <strong>다형성, 폴리모피즘(Polymorphism)</strong>이라고 부른다.</p>
<h2 id="see-more">See More</h2>
<p>Tiger 클래스의 객체는 다음과 같이 여러가지 자료형으로 표현할 수 있다.</p>
<pre><code class="language-java">Tiger tiger = new Tiger();
Animal animal = new Tiger();
Predator predator = new Tiger();
Barkable barkable = new Tiger();</code></pre>
<p>여기서 알아두어야 할 사항은 <code>Predator</code>로 선언된 predator 객체와 <code>Barkable</code>로 선언된 barkable 객체는 사용할 수 있는 메소드가 서로 다르다는 점이다. predator 객체는 <code>getFood()</code> 메소드가 선언된 <code>Predator</code> 인터페이스의 객체이므로 <code>getFood()</code> 메소드만 호출이 가능하다. 이와 마찬가지로 <code>Barkable</code> 로 선언된 barkable 객체는 <code>bark()</code> 메소드만 호출이 가능하다.</p>
<p> 만약 tiger 객체에서 <code>getFood</code>, <code>bark</code> 둘 다  사용하고 싶다면 어떻게 해야 할까?</p>
<ul>
<li><p><code>Predator</code>, <code>Barkable</code> 인터페이스를 구현한 <code>Tiger</code>로 선언된 tiger 객체를 사용하거나,</p>
</li>
<li><p>다음과 같이 <code>getFood</code>, <code>bark</code> 메소드를 모두 포함하는 새로운 인터페이스를 새로 만들어 사용하면 된다.<img src="https://images.velog.io/images/dmitry-_-11/post/7cdf2694-62eb-4c4a-b85b-6a70be50a624/image.png" alt=""><img src="https://images.velog.io/images/dmitry-_-11/post/6b8a8c15-8f10-4f57-874e-823b07729a80/image.png" alt=""></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Interface]]></title>
            <link>https://velog.io/@dmitry-_-11/Interface</link>
            <guid>https://velog.io/@dmitry-_-11/Interface</guid>
            <pubDate>Mon, 11 Jan 2021 09:36:30 GMT</pubDate>
            <description><![CDATA[<h2 id="usage">Usage</h2>
<p><img src="https://images.velog.io/images/dmitry-_-11/post/b68246bc-ca78-4b36-9c8c-8ead21d05dd4/image.png" alt=""><img src="https://images.velog.io/images/dmitry-_-11/post/95c9d1b6-f55c-40ab-9847-37fee5f0b349/image.png" alt=""><img src="https://images.velog.io/images/dmitry-_-11/post/c38d305d-258f-431e-9814-a0993afb835d/image.png" alt=""><img src="https://images.velog.io/images/dmitry-_-11/post/3a210db4-564d-4742-83c1-9352ebb47f07/image.png" alt=""><img src="https://images.velog.io/images/dmitry-_-11/post/0ec49b66-fd93-46f7-8142-e8bf7165c9f6/image.png" alt=""></p>
<h2 id="notes-on-interfaces-">Notes on Interfaces :</h2>
<ul>
<li><p>Like <strong>abstract classes</strong>, interfaces <strong>cannot</strong> be used to create objects </p>
</li>
<li><p>Interface methods do not have a body - the body is provided by the &quot;implement&quot; class</p>
</li>
<li><p>On implementation of an interface, you must override all of its methods</p>
</li>
<li><p>Interface methods are by default <code>abstract</code> and <code>public</code></p>
</li>
<li><p>Interface attributes are by default <code>public</code>, <code>static</code> and <code>final</code></p>
</li>
<li><p>An interface cannot contain a constructor (as it cannot be used to create objects)</p>
</li>
</ul>
<h2 id="why-and-when-to-use-interfaces">Why And When To Use Interfaces?</h2>
<ol>
<li><p>To achieve security - hide certain details and only show the important details of an object (interface).</p>
</li>
<li><p>Java <strong>does not support multiple inheritance</strong> (a class can only inherit from one superclass). Howerver, it can be achieved with interfaces, because the class can <strong>implement</strong> multiple interfaces.</p>
<p>*<em>Note : *</em>To implement multiple interfaces, separate them with a comma.</p>
<br/>

</li>
</ol>
<h2 id="see-more--java-interface"><a href="https://www.w3schools.com/java/java_interface.asp">See More : Java Interface</a></h2>
]]></description>
        </item>
    </channel>
</rss>