{"id":288,"date":"2009-09-16T07:51:45","date_gmt":"2009-09-16T07:51:45","guid":{"rendered":"http:\/\/kubasek.com\/blog\/pragmatic_craftsman\/?p=288"},"modified":"2009-09-16T07:51:45","modified_gmt":"2009-09-16T07:51:45","slug":"java-inner-classes-part-2-anonymous","status":"publish","type":"post","link":"https:\/\/pragmaticcraftsman.kubasek.com\/?p=288","title":{"rendered":"Java Inner Classes &#8211; Part 2 &#8211; Anonymous"},"content":{"rendered":"<p>In <a href=\"http:\/\/pragmaticcraftsman.com\/2009\/09\/java_inner_classes_-_intro_1.php\">Part 1, Java Inner Classes &#8211; Intro<\/a>, I covered most of the basics of inner classes. But there is much more. Some of it might get complex and confusing. But with all of that, I am beginning to understand and value what Bruce Eckel tries to say when he introduces inner classes.<\/p>\n<blockquote><p>At first, inner classes look like a simple code-hiding mechanism: You place classes inside other classes. You&#8217;ll learn, however, that the inner class does more than that&#8211;it knows about and can communicate with the surrounding class&#8211;and the kind of code you can write with inner classes is more elegant and clear, although there&#8217;s certainly no guarantee of this.<\/p>\n<p>Initially, inner classes may seem odd, and it will take some time to become comfortable using them in your designs. The need for inner classes isn&#8217;t always obvious, but after the basic syntax and semantics of inner classes have been described, the section &#8220;Why inner classes?&#8221; should begin to make clear the benefits of inner classes.<\/p><\/blockquote>\n<p>In part 2, I am going to cover even more obscure, but more advanced topics. I like to learn by example, this part is heavy on examples.<\/p>\n<h2>Local inner class<\/h2>\n<p>Did you know you can define a class within a method? Yes, you can. It&#8217;s called a <em>local inner class<\/em>. Example below.<\/p>\n<pre class=\"brush:java\">\n\/\/ Nesting a class within a method.\n\/\/ Example from Thinking in Java\npublic class Parcel5 {\n  public Destination destination(String s) {\n    <strong>class PDestination implements Destination {<\/strong>\n      private String label;\n      private PDestination(String whereTo) {\n        label = whereTo;\n      }\n      public String readLabel() {\n        return label;\n      }\n    }\n    return new PDestination(s);\n  }\n\n  public static void main(String[] args) {\n    Parcel5 p = new Parcel5();\n    Destination d = p.destination(\"Tasmania\");\n  }\n} \/\/ \/:~<\/pre>\n<h2>Class within a method<\/h2>\n<p>How about a class within an &#8220;if&#8221; statement. Yes, you can do that as well. It&#8217;s called a class within arbitrary scope, see below.<\/p>\n<pre class=\"brush:java\">\n\/\/ Nesting a class within a scope.\n\/\/ Thinking in Java example\npublic class Parcel6 {\n  private void internalTracking(boolean b) {\n    if (b) {\n      class TrackingSlip {\n        private String id;\n        TrackingSlip(String s) {\n          id = s;\n        }\n        String getSlip() {\n          return id;\n        }\n      }\n      TrackingSlip ts = new TrackingSlip(\"slip\");\n      String s = ts.getSlip();\n    }\n    \/\/ Can't use it here! Out of scope:\n    \/\/ ! TrackingSlip ts = new TrackingSlip(\"x\");\n  }\n\n  public void track() {\n    internalTracking(true);\n  }\n\n  public static void main(String[] args) {\n    Parcel6 p = new Parcel6();\n    p.track();\n  }\n} \/\/ \/:~<\/pre>\n<p>One other interesting part about the example above is that the class TrackingSlip will get compiled and a class file created. However, this class will only be accessible from within the scope it got created in.<\/p>\n<h2>Anonymous inner classes<\/h2>\n<p>Did you know you can return a class from inside the method body? A class that is not accessible from anywhere else. A class that has no name. Yes, that&#8217;s why it&#8217;s called anonymous. See example below.<\/p>\n<pre class=\"brush:java\">\n\/\/ Returning an instance of an anonymous inner class.\n\/\/ Thinking in Java example\npublic class Parcel7 {\n  public Contents contents() {\n    return new Contents() {\n      \/\/ Insert a class definition\n      private int i = 11;\n      public int value() {\n        return i;\n      }\n    }; Semicolon required in this case\n  }\n\n  public static void main(String[] args) {\n    Parcel7 p = new Parcel7();\n    Contents c = p.contents();\n  }\n} \/\/ \/:~<\/pre>\n<p>Observe the syntax. The first statement in the method body is a return statement. It looks like you are returning a new instance of a class or interface. But that&#8217;s not it. You are actually creating\/implementing the class, so you open a curly brackets { and close with }; and put the class definition inside. Very tricky and hard to get used to, I think.<\/p>\n<p><strong>Passing Arguments \/ Anonymous Constructor<\/strong>What if you need to pass an argument and do some constructor initialization. It turns out you can.<\/p>\n<pre class=\"brush:java\">\n\/\/ Creating a constructor for an anonymous inner class.\n\/\/ Thinking in Java example\nabstract class Base {\n  public Base(int i) {\n    print(\"Base constructor, i = \" + i);\n  }\n  public abstract void f();\n}\n\npublic class AnonymousConstructor {\n  public static Base getBase(int i) {\n    return new Base(i) {{\n      print(\"Inside instance initializer\");\n    }\n    public void f() {\n      print(\"In anonymous f()\");\n    }};\n  }\n  public static void main(String[] args) {\n    Base base = getBase(47);\n    base.f();\n  }\n}\n\/** Output:\nBase constructor, i = 47\nInside instance initializer\nIn anonymous\nf()\n*\/\/\/ :~<\/pre>\n<p>One note about arguments. If you&#8217;re using them inside the inner class, they have to be passed as final. In the above case, it&#8217;s not used directly so a non-final argument is fine.<\/p>\n<p>More: You can even define an instance variable in an inner class!<\/p>\n<p>Here&#8217;s a snippet from Thinking in Java that illustrates that:<\/p>\n<pre class=\"brush:java\">\npublic Destination destination(final String dest, final float price) {\n  return new Destination() {\n    private int cost;\n    \/\/ Instance initialization for each object:\n    {cost = Math.round(price);\n    if(cost &gt; 100)\n      System.out.println(\"Over budget!\");\n  }\n\n  private String label = dest;\n  public String readLabel() {\n    return label;\n  }};\n}\n<\/pre>\n<p>Note that in the above example, because price was used in the inner class, it had to be defined as final.<\/p>\n<p>Here&#8217;s a final note from Bruce about anonymous inner classes.<\/p>\n<blockquote><p>Anonymous inner classes are somewhat limited compared to regular inheritance, because they can either extend a class or implement an interface, but not both. And if you do implement an interface, you can only implement one.<\/p><\/blockquote>\n<p>More fun with inner classes to come! \ud83d\ude42 In Part 3, I&#8217;ll cover nested classes.<\/p>\n<p><strong>Reference<\/strong><br \/>\n<?php book(\"Thinking in Java (4th)\", \"0131872486\") ?>, Bruce Eckel<br \/>\n<a href=\"http:\/\/pragmaticcraftsman.com\/2009\/09\/java_inner_classes_-_intro_1.php\">Java Inner Classes &#8211; Part 1 &#8211; Intro<\/a>, The Pragmatic Craftsman<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Part 1, Java Inner Classes &#8211; Intro, I covered most of the basics of inner classes. But there is much more. Some of it might get complex and confusing. But with all of that, I am beginning to understand and value what Bruce Eckel tries to say when he introduces inner classes. At first, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[17,26,56],"class_list":["post-288","post","type-post","status-publish","format-standard","hentry","category-java","tag-advanced","tag-innerclass","tag-java"],"_links":{"self":[{"href":"https:\/\/pragmaticcraftsman.kubasek.com\/index.php?rest_route=\/wp\/v2\/posts\/288","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pragmaticcraftsman.kubasek.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pragmaticcraftsman.kubasek.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pragmaticcraftsman.kubasek.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pragmaticcraftsman.kubasek.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=288"}],"version-history":[{"count":0,"href":"https:\/\/pragmaticcraftsman.kubasek.com\/index.php?rest_route=\/wp\/v2\/posts\/288\/revisions"}],"wp:attachment":[{"href":"https:\/\/pragmaticcraftsman.kubasek.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=288"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pragmaticcraftsman.kubasek.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=288"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pragmaticcraftsman.kubasek.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=288"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}