11 inner classes Secret
Lead
Think of writing
- The origin of inner classes, as well as access to the internal characteristics of the class. Internal modification class member location and accessible format
- Why non-static inner classes to directly access external members of the class, because this class held by external references
- Local inner classes, you can only access the local variables are final modified
- Extending inner class, the internal class can inherit other class or implementing the external interface. ★★★★★
- Anonymous inner classes, format, principle
- Anonymous inner classes and inner classes of the conversion exercise. If you call multiple methods anonymous inner class
- Exercise anonymous inner classes, and face questions. Why write to hands ★★★★★
- Learn abnormal, as well as the difference between exceptions and errors
- Process underlying abnormality occurs
1. The origin of the inner classes, and access features within the class. Internal modification class member location and accessible format
/*
当A类中的内容要被B类直接访问,而A类还需要创建B的对象,访问B的内容时,
这时,可以将B类定义到A类的内部。这样访问更为便捷。
将B称之为内部类(内置类,嵌套类)。
访问方式:
内部类可以直接访问外部类中的所有成员,包含私有的。
而外部类要想访问内部类中的成员,必须创建内部类的对象。
当描述事物时,事物的内部还有事物,这个内部的事物还在访问外部事物中的内容。
这时就将这个事物通过内部类来描述。
【内部类被访问的方式】
情况一:内部类在成员位置上的被访问方式。
成员是可以被指定的修饰符所修饰的。
public:不多见:因为更多的时候,内部类已经被封装到了外部类中,不直接对外提供。
static:
*/
class Outer//外部类。
{
private static int num = 4;
public class Inner//内部类。
{
void show()
{
System.out.println("num="+num);
}
// static void show1(){}//非静态内部类中不允许定义静态成员。仅允许在非静态内部类中定义 静态常量 static final。
// 如果想要在内部类中定义静态成员,必须内部类也要被静态修饰。
}
/*
内部类被静态修饰后,随着Outer的加载而加载。可以把一个静态内部类理解为就是一个外部类。
*/
static class Inner2
{
void show2()
{
System.out.println("Inner2 show2 run..."+num);
}
static void staticShow()
{
System.out.println("Inner2 staticShow run");
}
}
void method()
{
/*Outer.*/Inner in = new /*Outer.*/Inner();
in.show();
}
}
class InnerClassDemo
{
public static void main(String[] args)
{
// Outer out = new Outer();
// out.method();
//测试情况一:直接访问Outer中的Inner内部类的非静态成员。
//创建内部类的对象就哦了。内部类作为成员,应该先有外部类对象,再有内部类对象。
// Outer.Inner in = new Outer().new Inner();
// in.show();
//测试情况二:对静态内部类中的非静态成员进行调用。
//因为内部类是静态,所以不需要创建Outer的对象。直接创建内部类对象就哦了。
// Outer.Inner2 in = new Outer.Inner2();
// in.show2();
// 如果静态内部类有静态成员,该如何访问呢?既然静态内部类已随外部类加载,而且静态成员随着类的加载而加载,
// 就不需要对象,直接用类名调用即可。
// Outer.Inner2.staticShow();
}
}
2. The non-static inner classes Why direct access to members of the outer class, because this class held by external references
/*
为什么内部类就能直接访问外部类中的成员呢?
那是因为内部类其实持有了外部类的引用 外部类.this
对于静态内部类不持有 外部类.this 而是直接使用 外部类名。
*/
class Outer
{
int num = 3;
class Inner
{
int num = 4;
void show()
{
int num = 5;
System.out.println("num="+num);
System.out.println("num="+this.num);
System.out.println("num="+Outer.this.num);
}
}
void method()
{
// System.out.println(num);
new Inner().show();
}
}
class InnerClassDemo2
{
public static void main(String[] args)
{
Outer out = new Outer();
out.method();
}
}
3. The local internal class can only access local variables be modified final
/*
内部类其实也可以定义在外部类的局部位置上。
内部类定义在局部时,只能访问被final修饰的局部变量。
为啥呢?因为编译生产的class中直接操作那个最终数值了。
为什么不能访问非最终的局部变量呢?
*/
class Outer
{
int num = 3;
void method()
{
final int x = 10;
// final int x = 5;//局部变量。
int y = 2;
class Inner//局部内部类。不能被成员修饰符修饰。
{
void show()
{
// System.out.println("y="+y);//访问失败。y的生命周期太短了。
System.out.println("x="+x);
System.out.println("inner show run........"+num);
}
}
new Inner().show();
}
}
/*
class Outer2
{
Object obj;
public void method()
{
int y = 9;
class Inner //extends Object
{
//覆盖了toString方法。
public String toString()
{
return "tostring:"+y;//假设可以访问y。
}
}
obj = new Inner();//给obj复制一个Inner对象。
}
public void function()
{
System.out.println(obj.toString());
}
}
*/
class InnerClassDemo3
{
public static void main(String[] args)
{
Outer out = new Outer();
out.method();
}
}
4. extending inner class, the internal class can inherit other class or implementing the external interface. ★★★★★
/*
内部类其实也可以定义在外部类的局部位置上。
内部类定义在局部时,只能访问被final修饰的局部变量。
为啥呢?因为编译生产的class中直接操作那个最终数值了。
为什么不能访问非最终的局部变量呢?
*/
class Outer
{
int num = 3;
void method()
{
final int x = 10;
// final int x = 5;//局部变量。
int y = 2;
class Inner//局部内部类。不能被成员修饰符修饰。
{
void show()
{
// System.out.println("y="+y);//访问失败。y的生命周期太短了。
System.out.println("x="+x);
System.out.println("inner show run........"+num);
}
}
new Inner().show();
}
}
/*
class Outer2
{
Object obj;
public void method()
{
int y = 9;
class Inner //extends Object
{
//覆盖了toString方法。
public String toString()
{
return "tostring:"+y;//假设可以访问y。
}
}
obj = new Inner();//给obj复制一个Inner对象。
}
public void function()
{
System.out.println(obj.toString());
}
}
*/
class InnerClassDemo3
{
public static void main(String[] args)
{
Outer out = new Outer();
out.method();
}
}
5. anonymous inner classes, format, principle
/*
内部类其实也可以定义在外部类的局部位置上。
内部类定义在局部时,只能访问被final修饰的局部变量。
为啥呢?因为编译生产的class中直接操作那个最终数值了。
为什么不能访问非最终的局部变量呢?
*/
class Outer
{
int num = 3;
void method()
{
final int x = 10;
// final int x = 5;//局部变量。
int y = 2;
class Inner//局部内部类。不能被成员修饰符修饰。
{
void show()
{
// System.out.println("y="+y);//访问失败。y的生命周期太短了。
System.out.println("x="+x);
System.out.println("inner show run........"+num);
}
}
new Inner().show();
}
}
/*
class Outer2
{
Object obj;
public void method()
{
int y = 9;
class Inner //extends Object
{
//覆盖了toString方法。
public String toString()
{
return "tostring:"+y;//假设可以访问y。
}
}
obj = new Inner();//给obj复制一个Inner对象。
}
public void function()
{
System.out.println(obj.toString());
}
}
*/
class InnerClassDemo3
{
public static void main(String[] args)
{
Outer out = new Outer();
out.method();
}
}
6. Conversion practice of anonymous inner classes and inner classes. If you call multiple methods anonymous inner class
/*
内部类其实也可以定义在外部类的局部位置上。
内部类定义在局部时,只能访问被final修饰的局部变量。
为啥呢?因为编译生产的class中直接操作那个最终数值了。
为什么不能访问非最终的局部变量呢?
*/
class Outer
{
int num = 3;
void method()
{
final int x = 10;
// final int x = 5;//局部变量。
int y = 2;
class Inner//局部内部类。不能被成员修饰符修饰。
{
void show()
{
// System.out.println("y="+y);//访问失败。y的生命周期太短了。
System.out.println("x="+x);
System.out.println("inner show run........"+num);
}
}
new Inner().show();
}
}
/*
class Outer2
{
Object obj;
public void method()
{
int y = 9;
class Inner //extends Object
{
//覆盖了toString方法。
public String toString()
{
return "tostring:"+y;//假设可以访问y。
}
}
obj = new Inner();//给obj复制一个Inner对象。
}
public void function()
{
System.out.println(obj.toString());
}
}
*/
class InnerClassDemo3
{
public static void main(String[] args)
{
Outer out = new Outer();
out.method();
}
}
7. Exercise anonymous inner classes, and face questions. Why write to hands ★★★★★
//匿名内部类练习。
interface Inter
{
public void show();
}
class Outer
{
//代码补足。要求使用匿名内部类。
public static Inter method()
{
//既然在Oute类中使用到了Inter的对象。可以使用内部类来完成。
//需要子类型,只要简化格式即可,因为接口中就只有一个方法。
return new Inter()
{
public void show()
{
//code..;
}
};
// return new Inner();
}
/*
// 还原成内部类。 当静态方法访问内部类时,内部类必须是静态的。
static class Inner implements Inter
{
public void show(){}
}
*/
}
//Outer$Inner.class 成员内部类Inner
//Outer$1Inner.class 局部内部类名称为Inner
//Outer$2.class//匿名内部类。
//面试题。
class Outer2
{
public void method()
{
//以下两个对象有区别吗?
new Object()
{
public void show(){}
}.show();//这个可以编译通过。
Object obj = new Object()
{
public void show(){}
};
// obj.show();//编译失败。为啥呢?因为匿名内部类是子类对象,当Object obj指向时,就被提升了Object。而Object类中没有定义show方法,编译失败。
}
// class Inner extends Object
// {
// public void show(){}
// }
}
class InnerClassDemo7
{
public static void main(String[] args)
{
Outer.method().show();
/*
Outer.method():Outer类中有一个method的方法。这个方式静态的。
Outer.method.show():能调用show()的必然是对象,说明method方法运算完应该返回一个对象。而且能调用Inter中的show方法,说明这个对象的类型是Inter。
*/
Inter in = Outer.method();new InterImpl();
in.show();
}
}
8. Learn abnormal, as well as the difference between exceptions and errors
/*
异常。
Java运行时期发生的问题就是异常。
Java中运行时发生的除了异常Exception还有错误Error。
异常:通常发生可以有针对性的处理方式的。
错误:通常发生后不会有针对性的处理方式。
Error的发生往往都是系统级别的问题,都是jvm所在系统发生的并反馈给jvm的。
无法针对处理,只能修正代码。
*/
class ExceptionDemo
{
public static void main(String[] args)
{
int[] arr = new int[1024*1024*100];//OutOfMemoryError
System.out.println(arr[0]);
System.out.println(arr[3]);//该句运行时发生了ArrayIndexOutOfBoundsException,导致程序无法继续执行。程序结束。
System.out.println("over");
}
}
9. underlying process abnormality occurs
/*
异常的发生细节。
*/
class Demo
{
/*
对给定的数组通过给定的角标获取元素。
*/
int getElement(int[] arr,int index)
{
/*
1,没有找到4个角标。运行时发生了问题,这个问题JVM认识。
这个问题java本身有描述:描述内容有:问题的名称,问题的内容,问题的发生位置。
既然有这么多的信息。java就将这些信息直接封装到对象中。ArrayIndexOutOfBoundsException
*/
int element = arr[index];//throw new ArrayIndexOutOfBoundsException(index);
return element;
}
}
class ExceptionDemo2
{
public static void main(String[] args)
{
Demo d = new Demo();
int[] arr = {34,12,67};
int num = d.getElement(arr,4);//收到 new ArrayIndexOutOfBoundsException(index); 抛出jvm。jvm进行最终处理。将问题的名称,信息,位置都显示屏幕上。
System.out.println("num="+num);
System.out.println("over");
}
}