前言:以前學習java的時候,學習java的靜態內部類,都只知道形式,可是卻不知道,靜態內部類是爲了什麼而出現,又是出現在哪些場景裏面,導致寫代碼的時候,基本沒有考慮到靜態內部類,而最近在看<effective java>時和工作上都不約而同的出現了靜態內部類,二者出現讓我再次思考,java的靜態內部類到底是幹什麼。
下面我並不會先說靜態內部類的原理,優點等等東西。我會先從引起我思考的現象開始講起。
下面是我們經常看到的代碼,爲了創建對象,給對象的每一個屬性都給他set值,這個本身並沒有問題,但當業務代碼一長,這個類的屬性越加越多,那麼每一次創建對象,又給他每個屬性賦值的代碼就會顯得又長又臭。業務代碼本身已經夠多,這個對象後面的初始化還要這麼長的代碼,就會讓代碼顯得臃腫。
package meide;
public class Person {
private String name;
private String sex;
private double height;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public static void main(String[] args) {
Person p = new Person();
p.setName("kris");
p.setSex("male");
p.setHeight(175.3);
}
}
因此,爲了後面代碼的簡潔與高效,我又看到另一種代碼:
package meide;
public class Person2 {
private String name;
private String sex;
private double height;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public static builder init(){
return new builder();
}
public Person2(builder builder){
name = builder.getName();
sex = builder.getSex();
height = builder.getHeight();
}
public static class builder{
private String name;
private String sex;
private double height;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public builder name(String name){
setName(name);
return this;
}
public builder sex(String sex){
setSex(sex);
return this;
}
public builder height(double height){
setHeight(height);
return this;
}
//1.先通過init創建builder
//2.再通過create返回對象
public Person2 create(){
return new Person2(this);
}
}
public static void main(String[] args) {
Person2 p2 = Person2.init().name("kris").sex("male").height(175.3).create();
System.out.println(p2.getName());
System.out.println(p2.getSex());
System.out.println(p2.getHeight());
}
}
從上面的代碼我們可以看到創建對對象並且初始化的代碼變得簡潔了,這樣面對衆多業務代碼的時候,就不顯得那麼臃腫了。
看完了上面的代碼,首先,我們知道了靜態內部類現實了構建器讓代碼簡潔了,那現在我們思考一下內部類。
在《Think in java》中:使用內部類最吸引人的原因是:每個內部類都能獨立地繼承一個(接口的)實現,所以無論外圍類是否已經繼承了某個(接口的)實現,對於內部類都沒有影響。--》內部類使用最明顯的例子就是list的迭代器就是用迭代器實現的。
/**
* Adapter to provide descending iterators via ListItr.previous
*/
private class DescendingIterator implements Iterator<E> {
private final ListItr itr = new ListItr(size());
public boolean hasNext() {
return itr.hasPrevious();
}
public E next() {
return itr.previous();
}
public void remove() {
itr.remove();
}
}
好,在看靜態內部類前,我們先看一下非靜態內部類,下面是我從別人那複製的代碼:
public class OuterClass {
private String name ;
private int age;
/**省略getter和setter方法**/
public class InnerClass{
public InnerClass(){
name = "chenssy";
age = 23;
}
public void display(){
System.out.println("name:" + getName() +" ;age:" + getAge());
}
}
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
innerClass.display();
}
}
--------------
Output:
name:chenssy ;age:23
在這裏,我們看到非靜態內部類的創建時需要外部類對象的引用的,而靜態內部類卻不需要外部類對象的引用,只需要外部類直接調靜態內部類的。其實當我們仔細思考的時候,靜態內部類用static修飾,
//時間有點晚,後面繼續