<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Peng-Yu Chen</title>
    <description>The latest articles on DEV Community by Peng-Yu Chen (@walkccc).</description>
    <link>https://dev.to/walkccc</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F535914%2Ff13ed801-0217-4622-9bed-fbcf779a19aa.jpeg</url>
      <title>DEV Community: Peng-Yu Chen</title>
      <link>https://dev.to/walkccc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/walkccc"/>
    <language>en</language>
    <item>
      <title>Java Wildcards Introduction</title>
      <dc:creator>Peng-Yu Chen</dc:creator>
      <pubDate>Tue, 08 Dec 2020 20:33:31 +0000</pubDate>
      <link>https://dev.to/walkccc/java-wildcards-demo-554f</link>
      <guid>https://dev.to/walkccc/java-wildcards-demo-554f</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The wildcard mark (&lt;code&gt;?&lt;/code&gt;) can help us write a program in a more explicit way.&lt;/p&gt;

&lt;p&gt;It's used to represent an unknown type and is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let's assume we have an object hierarchy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;Animal&lt;/code&gt; class inherits from &lt;code&gt;Object&lt;/code&gt; trivially&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Dog&lt;/code&gt; and &lt;code&gt;Cat&lt;/code&gt; classes both inherit from &lt;code&gt;Animal&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;GoldenRetriever&lt;/code&gt; class inherits from &lt;code&gt;Dog&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SInbnCCh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2zfg4qf68xu5fwv4xkef.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SInbnCCh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2zfg4qf68xu5fwv4xkef.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In general, there're 3 ways to use a wildcard:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Upper bound: &lt;code&gt;void fun(List&amp;lt;? extends Animal&amp;gt; list)&lt;/code&gt;&lt;br&gt;
This input list is parameterized over &lt;strong&gt;at most&lt;/strong&gt; type &lt;code&gt;Animal&lt;/code&gt; (can be any subtype of &lt;code&gt;Animal&lt;/code&gt;)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MLCCCVLs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o5g1jjaes4z2cry1334i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MLCCCVLs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o5g1jjaes4z2cry1334i.png"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lower bound: &lt;code&gt;void fun(List&amp;lt;? super Animal&amp;gt; list)&lt;/code&gt;&lt;br&gt;
This input list is parameterized over &lt;strong&gt;at least&lt;/strong&gt; type &lt;code&gt;Animal&lt;/code&gt; (can be any supertype of &lt;code&gt;Animal&lt;/code&gt;)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j78EjSHp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ncon0i6dgd11h9u64sfv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j78EjSHp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ncon0i6dgd11h9u64sfv.png"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Unbounded: &lt;code&gt;void fun(List&amp;lt;?&amp;gt; list) { list.clear(); }&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Here we don't care what the type of the list is since &lt;code&gt;clear()&lt;/code&gt; isn't type dependent.&lt;/li&gt;
&lt;li&gt;If we were supposed to use only methods defined in &lt;code&gt;Object&lt;/code&gt;, then unbounded wildcard works fine.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Java Demo Code
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;See the following code, &lt;code&gt;WildcardDemo.java&lt;/code&gt;, for better understanding.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, try to compile it with &lt;code&gt;javac WildcardDemo.java&lt;/code&gt; and see the error console :)&lt;/p&gt;

&lt;p&gt;Second, to successfully compile the code, note that there're 2 lines marked as &lt;code&gt;// X (can't compiled)&lt;/code&gt;, you should comment them in order to compile the code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The code is fully commented. Feel free to leave any comment if you're not understanding.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.ArrayList&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Arrays&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Our Object Hierarchy:
 *
 *          Object
 *            |
 *          Animal
 *           / \
 *        Dog   Cat
 *         |
 *  GoldenRetriever
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WildcardDemo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GoldenRetriever&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;

  &lt;span class="c1"&gt;// `animals` is parameterized over "at most" type `Animal`&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;funExtends&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Can't add a Dog (subtype) to the `animals` because it may&lt;/span&gt;
    &lt;span class="c1"&gt;// contain something "lower than an Animal".&lt;/span&gt;
    &lt;span class="c1"&gt;// For example, it might be `List&amp;lt;GoldenRetriever&amp;gt;` or `List&amp;lt;Cat&amp;gt;`&lt;/span&gt;
    &lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// X (can't compiled)&lt;/span&gt;

    &lt;span class="c1"&gt;// Can't put anything into a type declared with an extends&lt;/span&gt;
    &lt;span class="c1"&gt;// wildcard except for the value `null`, which is a subtype&lt;/span&gt;
    &lt;span class="c1"&gt;// of every reference type&lt;/span&gt;
    &lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Can retrieve an `Animal`, because any subtype of `Animal`&lt;/span&gt;
    &lt;span class="c1"&gt;// must be an `Animal`&lt;/span&gt;
    &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// `animals` is parameterized over "at least" type `Animal`&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;funSuper&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;super&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Can add a `Dog` (subtype) to the `animals` because a `Dog`&lt;/span&gt;
    &lt;span class="c1"&gt;// is guaranteed an `Animal` or any supertype of an `Animal`&lt;/span&gt;
    &lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

    &lt;span class="c1"&gt;// Can't get anything out from a type declared with a super&lt;/span&gt;
    &lt;span class="c1"&gt;// wildcard except for a value of type `Object`, which is a&lt;/span&gt;
    &lt;span class="c1"&gt;// super type of every reference type&lt;/span&gt;
    &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// X (can't compiled)&lt;/span&gt;
    &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getAnimals&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;GoldenRetriever&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Cat&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;WildcardDemo&lt;/span&gt; &lt;span class="n"&gt;demo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WildcardDemo&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;demo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAnimals&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;demo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;funExtends&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;demo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;funSuper&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
    </item>
  </channel>
</rss>
