内部クラス

普通内部クラス

static変数、staticメソッドとstatic内部クラスが含めない

public class OutterClass {

private int mOut = 10;

private int mMem = 20;

public class InnerClass {

private int mIn = 0;

private int mMem = 30;

public void printOutPrivate() {

//外部クラスのprivate変数にアクセス

System.out.println(mOut);

//同じprivate変数を区別

System.out.println(OutterClass.this.mMem);

}

}

public void printInPrivate() {

InnerClass in = new InnerClass();

//内部クラスのprivate変数にアクセス

System.out.println(in.mIn);

}

public void printOutPrivate() {

InnerClass in = new InnerClass();

in.printOutPrivate();

}

public InnerClass newInnerClass() {

return new InnerClass();

}

public static void main(String[] args) {

OutterClass out = new OutterClass();

out.printInPrivate();

out.printOutPrivate();

//外部クラスのインスタンスが必要

OutterClass.InnerClass in = out.new InnerClass(); //方法1

OutterClass.InnerClass in = out.newInnerClass(); //方法2

in.printOutPrivate();

}

}

静的内部クラス

外部クラスがpackage名に相当する

public class OutterClass {

private int mOut = 10;

public static class InnerClass {

private int mIn = 0;

public void printOutPrivate() {

//外部クラスのprivate変数にアクセスできない

//System.out.println(mOut);

}

}

public void printInPrivate() {

InnerClass in = new InnerClass();

//内部クラスのprivate変数にアクセス

System.out.println(in.mIn);

}

public void printOutPrivate() {

InnerClass in = new InnerClass();

in.printOutPrivate();

}

public InnerClass newInnerClass() {

return new InnerClass();

}

public static void main(String[] args) {

//外部クラスのインスタンスが不要

OutterClass.InnerClass in = new InnerClass(); //方法1

OutterClass.InnerClass in = out.newInnerClass(); //方法2

in.printOutPrivate();

}

}

サンプル

public class Person {

private String name;

private Home home;

public Person(String name) {

this.name = name;

}

// getter/setter

public static class Home{

private String address;

private String tel;

public Home(String address, String tel) {

this.address = address;

this.tel = tel;

}

// getter/setter

}

}

Person p = new Person("Andy");

p.setHome(new Person.Home("Tokyo", "03-xxx"));

静的内部クラスと普通内部クラスの区別

1.静的内部クラスはstatic変数・メソッドのみをアクセスできる

2.普通内部クラスは外部クラスを依頼するが、静的内部クラスと外部クラスはそれぞれ独立

3.普通内部クラスはstatic変数・メソッドを宣言できない、静的内部クラスは制限なし

ローカル内部クラス

public class OutterClass {

public Hello testLocalInner() {

class LocalInner implements Hello {

@Override

public void print() {

//do something

}

}

return new LocalInner();

}

public static void main(String[] args) {

OutterClass out = new OutterClass();

Hello hello = out.testLocalInner();

hello.print();

}

}

匿名クラス

public class OutterClass {

private int field = 5;

public void print(final String param){

final int local = 10;

Hello hello = new Hello() {

@Override

public void print() {

System.out.println(local);

System.out.println(param);

System.out.println(field);

}

};

hello.print();

}

//戻り値の場合

public Hello testAnonymousInner() {

return new Hello() {

@Override

public void print() {

//do something

}

};

}

//引数の場合

public void testAnonymousInner2(Hello hello) {

hello.print();

}

public static void main(String[] args) {

OutterClass out = new OutterClass();

Hello hello = out.testAnonymousInner();

hello.print();

out.testAnonymousInner2(new Hello() {

@Override

public void print() {

//do something

}

});

}

}

List l = new ArrayList(){};

下記と同じ

class Sub extends ArrayList{

}

List l = new Sub();

List l = new ArrayList(){{}};

下記と同じ

class Sub extends ArrayList{

{

// 初期化

}

}

List l = new Sub();

※List l = new ArrayList(){{}{}{}};でもOK

サンプル

class Test{

private int i;

private int j;

public Test(){}

public Test(int i, int j){

this.i = i;

this.j = j;

}

protected void methodA(){

// do something

}

public int methodB(){

// do something

}

}

Test t = new Test(2, 3){

{

methodA();

}

};

t.methodB();

下記と同じ

class Sub extends Test{

{

methodA();

}

public Sub(int i, int j){

super(i, j);

}

}

Test t = new Sub(2, 3);

t.methodB();