第一種方式:getClass
getClass獲取類首先需要有實例化對象
Date date = new Date();
Class<?> cls = date.getClass();
System.out.println(cls.getName());
第二種方式:.class
.class獲取類不需要有實例化對象,但是需要完整類名
Class<?> cls2 = java.util.Date.class;
System.out.println(cls2.getName());
第三種方式:.forName()
調用.forName()需要有完整的類名
Class<?> cls3 = Class.forName("java.util.Date");
System.out.println(cls3.getCanonicalName());
運行結果:
學了上面的三種主要獲取類方式,那麼來實踐玩玩吧
把之前寫的工廠方法模式拿出來看看存在的問題,還沒看的或者有興趣的可以看看,當然不看也行,因爲我這裏會重新敲一遍工廠模式(爲什麼要重新敲呢?相當於一個簡單的重構吧,讓代碼更健壯一點點,哈哈…)
好了,鏈接放就這,然後來看看下面的問題
簡單工廠模式裏的工廠類(也是靜態工廠模式):每次出新的手機牌子就需要修改工廠類違反開閉原則
工廠方法模式呢?看看消費者類獲取手機需要new,我們都知道解決耦合的關鍵是取消new,因爲new是耦合的最大元兇,所以我們接下來用反射來幫助我們解決設計上的缺陷。
來,利用反射對工廠模式解耦操作!
Phone接口
public interface Phone {
void getBrand();
}
Meizu品牌類
public class Meizu implements Phone {
@Override
public void getBrand() {
System.out.println("魅族");
}
}
Xiaomi品牌類
public class Xiaomi implements Phone {
@Override
public void getBrand() {
System.out.println("小米");
}
}
PhoneFactory工廠類
利用最開始講的反射三種獲取對象之一的Class.forName(傳入完整的包類名)找到它的類,然後使用newInstance()方法反射的對象實例化
public class PhoneFactory {
public static Phone getInstance(String orgin) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class<?> cls = Class.forName(orgin);
Phone brand = (Phone)cls.newInstance();
return brand;
}
}
Customer 消費者類,直白一點說就是可以傳值了,而無需用new寫死
public class Customer {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
PhoneFactory.getInstance("Factory.Xiaomi").getBrand();
PhoneFactory.getInstance("Factory.Meizu").getBrand();
}
}
運行結果:
可以看到上面代碼可以說和靜態工廠模式一樣,只不過工廠模式利用了反射機制,不再只是用new關鍵字而是用反射機制來。
最後
實踐一波後會發現,對象實例化不再是單獨用new來,反射也是可以完成的(當然反射還是需要考慮到性能的,這是後話,到時可以一起來探究一下原理),當然這不表示new會完全被取代,在一些開發中也會經常用到new這個關鍵字