Inner Class-Grammar chapter

Source: Internet
Author: User
Tags getbase

Zen House Moon (Http://www.cnblogs.com/yaoyinglong)

1. What is an internal class

It is simply a class, interface, or method that is created within a category. The method of creating an inner class is clear in this sense.

 PackageCom.gissky.innerClass; Public classPath { Public classstart{ PublicStart (String start) { This. start=start; }        PrivateString start;  PublicString Getstart () {returnstart; }    }     Public classend{ PublicEnd (String end) { This. end=end; }        PrivateString end;  PublicString getend () {returnend; }    }}
2. Instantiation of the Inner class 2.1 non-static method internalInstantiation, this is simple, as we usually do.
 Public start Start (String start) {    returnnew  start (start);  Public End End (String end) {    returnnew  End (end);}
2.2 In the outer class non-static method externalTo create an inner class object anywhere, you must specify the type of the object, namely: Outerclassname.innerclassname, and must be done with an external class object, similar to the following: The perimeter class object. New inner Class ();Such a syntax.
 Public Static void Main (string[] args) {    path path=new  Path ();    Path.start Start=path. New Start ("My Home");    Path.end End=path. New End ("Fu Zhou");    Path. Go (start, end);}
3. The inner class has a pointer to an external class. ObjectThe reference

The inner class has access to all elements of its outer class. How is this done? Modify the above program:

 Public classPath {Private DoubleStartTime; Private DoubleEndTime;  Public classstart{ PublicStart (String start) {startTime=NewDate (). GetTime ();  This. start=start; }        PrivateString start;  PublicString Getstart () {returnstart; }    }     Public classend{ PublicEnd (String end) { This. end=end; EndTime=NewDate (). GetTime (); }        PrivateString end;  PublicString getend () {returnend; }    }         Public voidGo (Start start,end End) {System.out.println ("Start to End"); System.out.println (EndTime-startTime); }     Publicstart Start (String start) {return Newstart (start); }     PublicEnd End (String end) {return Newend (end); }}

This is the compiler that has helped us generate 3. class files:

The two are the. class files of the compiler-generated inner classes, and it is strange that they are preceded by the name of their outer class plus $ and their class. Let's take a look at the JAVAP anti-compile tool:

From this we can know that the member variables of the inner class that access the outer class are made by a static method that invokes the outer class, which must pass in a reference to a perimeter class.

It should be understood here that "when creating an inner class object anywhere outside of a non-static method of an external class, you must specify the type of the object, namely: Outerclassname.innerclassname, and must be done with an external class object", as mentioned in 2.2. The reason for it. That's because the inner class is connected to the Outer class object on which it was created.

Isn't there a security risk? There is a lot of reason for this worry. Anyone can easily read to the private domain beep by calling the Access$0 method. Of course, access$0 is not a valid Java method name. But hackers familiar with the class file structure can use the hex editor to easily create a class file that invokes that method with a virtual machine directive. due to hidden The ground access method needs to have package visibility, so the attack code needs to be placed in the same package as the attacked class.

In summary, if the inner class accesses the private data domain, it is possible to access them by attaching other classes in the package that the perimeter class is in, but doing so requires great skill and determination. programmers cannot inadvertently gain access to the class , and must deliberately build or modify the class file to be able to achieve this. 4. Static Inner class

First, the static inner class does not have as many restrictions as a normal inner class, and it does not require a reference to an external partial object.

Sometimes an inner class is used only to hide a class inside another class and does not require an inner class to refer to the Outer class object. To do this, you can declare the inner class as static in order to cancel the resulting reference.

Note: a static inner class should be used when the inner class does not need to access the perimeter class object. Some programmers use nested classes (nested Class) to represent static inner classes.

Note: an inner class declared in an interface automatically becomes static and public. 5. Inner class and upward transformation

 Public Interface Fly {    publicvoid  fly ();}
 Public classAnimal {Private classBirdImplementsfly{@Override Public voidFly () {System.out.println ("Bird.flu ()"); }        }         PublicFly bfly () {return NewBird (); }     Public Static voidMain (string[] args) {Animal Animal=NewAnimal (); Fly Fly=Animal.        Bfly ();    Fly.fly (); }}

The above code shows that we cannot transform the fly interface downward because we cannot know the name of the inner class bird (it is private). Therefore, the private inner class can completely block any type-dependent encoding. The client cannot access any newly added interfaces in the inner class, so the extension interface is worthless (blocking the appearance of the Is-like-a form). And because the inner class is private, it is completely invisible to the client and is not available. The resulting knowledge points to the reference of the base class or interface, which conveniently hides the implementation details.

6. Local inner class

That is, the inner class that is defined within the method and scope. Reason to use: Use a class to assist your program for some reason in your method or scope, but you don't want the class to be public.

For example, such a requirement: I do an evaluation work, I select the indicator, and then according to different indicators to allow users to choose different models to calculate the evaluation value of the indicator. In this way, I need to record: The indicator name, model name, model parameters. It is then calculated by reflection. In the actual work I designed this:

 PublicInfmodel Execute (Infmodel infmodel, String measure, Users user) {//Region Inner Class--the model and parameters used to construct each indicator        classmodel{ PublicMethod Execute;  PublicObject intance;  PublicString Modelparam; /**Constructor *@parammethod interface for execute model execution *@paramintance Model Instance *@paramModelparam parameters required to construct the model*/             PublicModel (Method execute,object intance, String modelparam) { This. modelparam=Modelparam;  This. execute=Execute;  This. intance=intance; }        }        //endregion//Follow-up work}

Local classes cannot be declared with public or private access specifiers. Its scope is scoped to the block that declares the local class.

Local classes have an advantage in that they can be completely hidden from the outside world. In addition to the Execute method, there is no way to know the model class exists. 7. Anonymous inner class

 Public classAnonymousinnerclass { PublicDestination Destination (FinalString dest) {        return NewDestination () {@Override PublicString Readlabel () {returndest;    }        }; }     Public Static voidMain (string[] args) {Anonymousinnerclass AIC=NewAnonymousinnerclass (); System.out.println (Aic.destination (Ends). Readlabel ()); }}

As you can see from the code above, an anonymous inner class is an inner class that has no class name. Therefore do not want to add an interface in the anonymous inner class that does not have a base class (because the addition is also Barker, the outside is inaccessible). However, some private members can be added in order to achieve this. At the same time, we also notice that within the inner class , when you want to use an object that is set externally, the compiler requires that its parameter application must be final.

Why does this parameter have to be final? To this end we examine the control process carefully.

    1. Call the destination method;
    2. Call new Destination () to create an inner class;
    3. The destination method ends, at which point the dest parameter of the destination method no longer exists.
    4. Then, somewhere in the future, destination calls the Readlabel method, return dest.

At this time in the inner class produced a "closure", the closure will make dest out of its way to continue to exist, so that in the Readlabel method can be arbitrarily modified dest, but the external class is completely unknown. Therefore, the dest must be final.

In fact, in order to allow the Readlabel method to work, the destination class (here is an anonymous inner class, the compiler gives it the name anonymousinnerclass$1. Class) to back up the dest domain in its own constructor before the Dest domain is released.

The above example is possible for an interface or a class that has no parameter constructors. But what happens when the constructor of a class has parameters? Quite simply, we would like to construct a class with the constructor as a new one:

 Public Abstract class Base {    {        System.out.println ("base instane initializer");    }      Public Base (int  i) {        System.out.println ("base constructor, i=" +i);    }      Public Abstract void f ();}
 Public classAnonymousinnerclass { Public StaticBase GetBase (int i) {        return NewBase (i) {{System.out.println ("Inside Instane initializer"); } @Override Public voidf () {System.out.println ("In Anonymousinnerclass F ()");    }        }; }     Public Static voidMain (string[] args) {Base base=getbase (5);    BASE.F (); }}

We find that the variable I here does not require that it be final, why is it? Because, this is the variable i is not used inside the internal class, but is passed to its base class constructor, it is not in the anonymous inner class is directly used.

Inner Class-Grammar chapter

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.