枚举类、内部类、final、this注意事项
1.从Java 5开始有了枚举类,需要注意的是enum定义的类默认继承的是java.lang.Enum类而不是Object类。
同时注意枚举类不能派生子类(类的默认修饰符为final),其原因基于它只有private构造器,那为什么要设计成这样呢?
其实很容易想明白,所谓枚举类就是有包含有固定数量实例(并且实例的值也固定)的特殊类,如果其含有public构造器,
那么在类的外部就可以通过这个构造器来新建实例,显然这时实例的数量和值就不固定了,这与定义枚举类的初衷相矛盾,
为了避免这种形象,就对枚举类的构造器默认使用private修饰。如果为枚举类的构造器显式指定其它访问控制符,
则会编译出错。另外,注意枚举类的所有实例必须在其首行显式列出,否则它不能产生实例。
2.Java枚举类是从Java5开始支持的。
枚举类的构造方法是用private修饰的。枚举类的所有实例必须在类的第一行列出,否则这个枚举类不会产生对象。
而且这些实例都是public static void.
每个枚举类都有一个values方法,该方法可以遍历枚举类的所有实例
3.一旦为枚举类定义了带参数的构造方法后,列举枚举类就必须对应的传入参数
4.枚举类实现接口与普通类一样,枚举类实现接口,则必须实现接口中所有的方法,也可以使用匿名内部类的方法为每一个枚举类对象实现接口
5.包含抽象方法枚举类,要实例化对象的话,就得让每个对象实现抽象方法
1.内部类不是很好理解,但说白了其实也就是一个类中还包含着另外一个类
如同一个人是由大脑、肢体、器官等身体结果组成,而内部类相当于其中的某个器官之一,例如心脏:它也有自己的属性和行为(血液、跳动)
显然,此处不能单方面用属性或者方法表示一个心脏,而需要一个类,而心脏又在人体当中,正如同是内部类在外部类当中
2.内部类其实严重破坏了良好的代码结构,但为什么还要使用内部类呢?
因为/*内部类可以随意使用外部类的成员变量(包括私有)而不用生成外部类的对象*/,这也是内部类的唯一优点
如同心脏可以直接访问身体的血液,而不是通过医生来抽血
3.程序编译过后会产生两个.class文件,分别是Out.class和Out$In.class,其中$代表了上面程序中Out.In中的那个 .
Out.In in = new Out().new In()可以用来生成内部类的对象,这种方法存在两个小知识点需要注意
(1).开头的Out是为了标明需要生成的内部类对象在哪个外部类当中
(2).必须先有外部类的对象才能生成内部类的对象,因为内部类的作用就是为了访问外部类中的成员变量
4.内部类在没有同名成员变量和局部变量的情况下,内部类会直接访问外部类的成员变量,而无需指定Out.this.属性名;否则,
内部类中的局部变量会覆盖外部类的成员变量,而访问内部类本身的成员变量可用this.属性名,访问外部类的成员变量需要使用Out.this.属性名。
5.如果用static 将内部类静态化,那么内部类就只能访问外部类的静态成员变量,具有局限性;其次,因为内部类被静态化,因此Out.In可以
当做一个整体看,可以直接new 出内部类的对象(通过类名访问static,生不生成外部类对象都没关系)。
6.如果一个内部类只希望被外部类中的方法操作,那么可以使用private声明内部类
上面的代码中,我们必须在Out类里面生成In类的对象进行操作,而无法再使用Out.In in = new Out().new In() 生成内部类的对象
也就是说,此时的内部类只有外部类可控制。如同是,我的心脏只能由我的身体控制,其他人无法直接访问它。
7.我们将内部类移到了外部类的方法中,然后在外部类的方法中再生成一个内部类对象去调用内部类方法,如果此时我们需要往外部类的方法中传入参数,
那么外部类的方法形参必须使用final定义,至于final在这里并没有特殊含义,只是一种表示形式而已
1.final从字面上理解含义为“最后的,最终的”。在Java中也同样表示出此种含义。
final可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。
2.final修饰类:
final修饰类即表示此类已经是“最后的、最终的”含义。因此,用final修饰的类不能被继承,即不能拥有自己的子类。
如果试图对一个已经用final修饰的类进行继承,在编译期间或发生错误。
3.final修饰方法:
final修饰的方法表示此方法已经是“最后的、最终的”含义,亦即此方法不能被重写(可以重载多个final修饰的方法)。
此处需要注意的一点是:因为重写的前提是子类可以从父类中继承此方法,如果父类中final修饰的方法同时访问控制权限为private,
将会导致子类中不能直接继承到此方法,因此,此时可以在子类中定义相同的方法名和参数,此时不再产生重写与final的矛盾,而是
在子类中重新定义了新的方法。
4.final 修饰变量:
final修饰的变量表示此变量是“最后的、最终的”含义。一旦定义了final变量并在首次为其显示初始化后,final修饰的变量值不可被改变。
这里需要注意以下几个问题:
(1) final修饰的变量,无论是类属性、对象属性、形参还是局部变量,这些变量都是需要进行显示初始化(即为其显示指定初始值)。
(2)对于final修饰的形参,由于是实参传递过来的,很好理解。
(3)对于final修饰的局部变量,与未用final修饰的变量一样,都是需要显示初始化。即局部变量都是需要显示初始化的。
(4)对于一般的类属性和对象属性,由类和对象的初始化过程中可以看出,首先都进行了默认初始化。然后对有显示赋值的变量才再进行显示初始化。
但对final修饰的类属性和对象属性而言,如果不显示初始化,其默认将是进行默认初始化后的值,这与final本身出发点矛盾,因此,Java语法规定:
final修饰的类属性和变量属性必须要进行显示初始化赋值。
另外,无论对于基本数据类型还是引用数据类型,final修饰的变量都是首次显示初始化后值都不能修改。对于基本数据类型,很好理解。对于引用
数据类型,引用变量指向的是实际的对象,但其存储的是所指向对象的地址,因此,其值不能修改并不意味着其所指向的对象不能修改。
5.final修饰变量后导致的“宏替换”/"宏变量"问题
Java 中宏变量/宏替换指的是在java代码中在编译期某些变量能够直接被其本身的值所替换,编译到.class文件中。因此,编译后的.class文件中已经不存在此变量了。
6.final修饰符修饰的变量在由于其本身的特性,在编译期就能直接确定其值,且此值不可变。在编译过程中,可以直接将其变量直接转换成其值本身去表示。
1.this主要要三种用法:
(1)、表示对当前对象的引用!
(2)、表示用类的成员变量,而非函数参数,注意在函数参数和成员变量同名是进行区分!其实这是第一种用法的特例,比较常用,所以那出来强调一下。
(3)、用于在构造方法中引用满足指定参数类型的构造器(其实也就是构造方法)。但是这里必须非常注意:只能引用一个构造方法且必须位于开始!
还有就是注意:this不能用在static方法中!所以甚至有人给static方法的定义就是:没有this的方法!
虽然夸张,但是却充分说明this不能在static方法中使用!
2.其他任何方法都不能调用构造器,只有构造方法能调用他。
但是必须注意:就算是构造方法调用构造器,也必须为于其第一行,构造方法也只能调用一个且仅一次构造器
3.引用类的成员变量、调用构造器、返回一个类型的对象。

浙公网安备 33010602011771号