摘要:通過運行時類型信息,程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對象的實際派生類型。編程應該盡量面向接口編程,應該對類型信息盡量的少了解二對象看書,書上寫得好靜態語句塊在這個類被加載的時候運行。
一、為什么需要RTTI
Run-Time Type Information。通過運行時類型信息,程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對象的實際派生類型。
編程應該盡量面向接口編程,應該對類型信息盡量的少了解
package tij.classinfomation; import java.util.Arrays; import java.util.List; public class Test { public static void main(String[] args) { List二、Class對象shapeList = Arrays.asList(new Circle(), new Square(), new Triangle()); for (Shape shape : shapeList) { shape.draw(); } } } abstract class Shape { void draw() { System.out.println(this + ".draw"); } abstract public String toString(); } class Circle extends Shape { public String toString() { return "Circle"; } } class Square extends Shape { public String toString() { return "Square"; } } class Triangle extends Shape { public String toString() { return "Triangle"; } }
看書,書上寫得好
package tij.classinfomation; public class Test { public static void main(String[] args) { System.out.println("inside main"); new Candy(); System.out.println("After creating Candy"); try { Classclazz = Gum.class; String class_name = clazz.getName(); System.out.println(class_name); Class.forName(class_name); } catch (ClassNotFoundException e) { System.out.println("Couldn"t find Gum"); } System.out.println("After Class.forname("Gum")"); new Cookie(); System.out.println("After creating Cookies"); } } class Candy { static { System.out.println("Loading Candy"); } } class Gum { static { System.out.println("Loading Gum"); } } class Cookie { static { System.out.println("Loading Cookie"); } }
靜態語句塊在這個類被加載的時候運行。
其中Class.forName方法中要寫類的絕對路徑,包名+類名,同時調用Gum.class.getName的時候,也并沒有加載Gum類。
另外
class tt{ static void showt(){ System.out.println("showt"); } static{ System.out.println("ttstatic"); } } class jj extends tt{ static void showj(){ System.out.println("showj"); } static{ System.out.println("jjstatic"); } } public class Test { public static void main(String[] args) { jj.showt(); } }
雖然調用的事jj.showt,但是并沒有加載jj這個類,而是加載了tt這個類。
所以就驗證了,運行時是實際用誰了,才加載誰
package tij.classinfomation; public class Test { public static void main(String[] args) { Class c = null; try { c = Class.forName("tij.classinfomation.FancyToy"); } catch (ClassNotFoundException e) { System.out.println("Can"t find FancyToy"); System.exit(1); } ToyTest.printInfo(c); System.out.println("-----------------"); for (Class face : c.getInterfaces()) { ToyTest.printInfo(face); } System.out.println("-----------------"); Class up = c.getSuperclass(); Object obj = null; try { obj = up.newInstance(); } catch (InstantiationException e) { System.out.println("Cannot instantiate"); System.exit(1); } catch (IllegalAccessException e) { System.out.println("Cannot access"); System.exit(1); } ToyTest.printInfo(obj.getClass()); } } interface HasBatteries {} interface Waterproof {} interface Shoots {} class Toy { Toy() {} Toy(int i) {} } class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots { FancyToy() { super(1); } } class ToyTest { static void printInfo(Class cc) { System.out.println("Class name:" + cc.getName() + " is interface?[" + cc.isInterface() + "]"); System.out.println("Simple name:" + cc.getSimpleName()); System.out.println("Canonical name:" + cc.getCanonicalName()); } }
看書
1.類字面常量類字面常量就是
FancyToy.class;
基本類型也可以用的,這個方法不會自動初始化這個類對象
要使用類的話,要進行三個步驟
package tij.classinfomation; import java.util.Random; public class Test { public static void main(String[] args) throws ClassNotFoundException { Class initable = Initable.class; System.out.println("After Initable ref"); System.out.println(Initable.staticFinal); System.out.println(Initable.staticFinal2); System.out.println(Initable2.staticNonFinal); Class initable3 = Class.forName("tij.classinfomation.Initable3"); System.out.println("After creating Initable3 ref"); System.out.println(Initable3.staticNonFinal); } } class Initable { static final int staticFinal = 47; static final int staticFinal2 = new Random(47).nextInt(1000); static { System.out.println("Initializing Initable"); } } class Initable2 { static int staticNonFinal = 147; static { System.out.println("Initializing Initable2"); } } class Initable3 { static int staticNonFinal = 74; static { System.out.println("Initializing Initable3"); } }2.泛化的Class引用
ClassgenericIntClass=int.class;
這是錯的
Class extends Number> genericIntClass = Integer.class;
這個可以
Class> genericIntClass = Integer.class;
有個>比class光桿優雅
package tij.classinfomation; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) throws ClassNotFoundException { FilledListfl = new FilledList<>(CountedInteger.class); System.out.println(fl.create(15)); } } class CountedInteger { private static long counter; private final long id = counter++; public String toString() { return Long.toString(this.id); } } class FilledList { private Class type; public FilledList(Class type) { this.type = type; } public List create(int nElements) { List result = new ArrayList (); for (int i = 0; i < nElements; i++) { try { result.add(type.newInstance()); } catch (Exception e) { e.printStackTrace(); } } return result; } }
B.class.getSuperclass()指的是“某各類,且是B的父類”
Class指的是“A類”
這兩個是有區別的
沒啥卵用= =就是類型裝換嘛
三、類型轉換前先做檢查看書吧= =這段太費勁了。
四、注冊工廠要在已有的繼承關系中添加新的繼承關系,最合適的就是應該將新添加的類再父類中完成注冊。
結合工廠設計模式
package tij.classinfomation; import java.util.ArrayList; import java.util.List; import java.util.Random; public class Test { public static void main(String[] args) { for (int i = 0; i < 10; i++) { System.out.println(Part.createRandom()); } } } class Part { public String toString() { return this.getClass().toString(); } static List> partFactories = new ArrayList<>(); static { partFactories.add(new FuelFilter.Factory()); partFactories.add(new AirFilter.Factory()); partFactories.add(new CabinAirFilter.Factory()); partFactories.add(new FanBelt.Factory()); } private static Random rand = new Random(47); static Part createRandom() { int n = rand.nextInt(partFactories.size()); return partFactories.get(n).create(); } } interface Factory { T create(); } class Filter extends Part {} class FuelFilter extends Filter { public static class Factory implements tij.classinfomation.Factory { public FuelFilter create() { return new FuelFilter(); } } } class AirFilter extends Filter { public static class Factory implements tij.classinfomation.Factory { public AirFilter create() { return new AirFilter(); } } } class CabinAirFilter extends Filter { public static class Factory implements tij.classinfomation.Factory { public CabinAirFilter create() { return new CabinAirFilter(); } } } class Belt extends Part {} class FanBelt extends Belt { public static class Factory implements tij.classinfomation.Factory { public FanBelt create() { return new FanBelt(); } } }
任何新添加的子類,只要在part類中新添加一個add就可以完成注冊了。
另外此處運用到了工廠方法,往列表里添加的也是一個工廠對象,這樣的意義在于將創建對象的任務交給各個對象自己的工廠來辦,利用多態的性質,在新添加的類中相似實現工廠可以達到生成新的子類的對象的目的。
package tij.classinfomation; public class Test { public static void main(String[] args) { FamilyVsExactType.test(new Derived()); FamilyVsExactType.test(new Base()); } } class Base {} class Derived extends Base {} class FamilyVsExactType { static void test(Object x) { print("Tseting x of type " + x.getClass()); print("x instanceof Base " + (x instanceof Base)); print("x instanceof Derived " + (x instanceof Derived)); print("Base.isInstance(x) " + (Base.class.isInstance(x))); print("Derived.isInstance(s) " + Derived.class.isInstance(x)); print("x.getClass()==Base.class " + (x.getClass() == Base.class)); print("x.getClass().equals(Base.class) " + (x.getClass().equals(Base.class))); print("x.getClass()==Derived.class " + (x.getClass() == Derived.class)); print("x.getClass().equals(Derived.class) " + (x.getClass().equals(Derived.class))); } static void print(String s) { System.out.println(s); } }六、反射:運行時的類信息
package tij.classinfomation; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.regex.Pattern; public class Test { private static String usage = "usage: " + "ShowMethods qualified.class.name " + "To show all methods in class or: " + "ShowMethods qualified.class.name word " + "To search for methods involving "word""; private static Pattern p = Pattern.compile("w+."); public static void main(String[] args) { Class> c = Test.class; Method[] methods = c.getMethods(); for (Method method : methods) { System.out.println(p.matcher(method.toString()).replaceAll("")); } Constructor[] ctors = c.getConstructors(); for (Constructor constructor : ctors) { System.out .println(p.matcher(constructor.toString()).replaceAll("")); } } }七、動態代理
package tij.classinfomation; public class Test { public static void main(String[] args) { Interface Aface = new RealObject(); Aface.doSomething(); Aface.somethingElse("bonobo"); System.out.println("------------"); Interface Bface = new SimpleProxy(Aface); Bface.doSomething(); Bface.somethingElse("bonobo"); } } interface Interface { void doSomething(); void somethingElse(String arg); } class RealObject implements Interface { public void doSomething() { System.out.println("doSomething"); } public void somethingElse(String arg) { System.out.println("somethingElse " + arg); } } class SimpleProxy implements Interface { private Interface proxied; public SimpleProxy(Interface proxied) { this.proxied = proxied; } public void doSomething() { System.out.println("SimpleProxy doSomething"); proxied.doSomething(); } public void somethingElse(String arg) { System.out.println("SimpleProxy somethingElse " + arg); proxied.somethingElse(arg); } }
我覺得這塊講的不是很好,CZ那邊這里講的就很好。
八、空對象沒懂= =
end
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/67589.html
摘要:迭代器解決了這個問題。刪除后于是我們可以寫一個方法,接受一個類型,然后讓他調用方法,這就不需要考慮這個是個還是了,也就是說,可以將遍歷容器的操作與序列底層的結構分離,迭代器統一了對容器類的訪問方式。十二和兩種遍歷的方法,與迭代器方法。 一、泛型和類型安全的容器 package tij.hoding; import java.util.ArrayList; public class ...
摘要:四上的操作看五格式化輸出運用和語言很相似和是等價的喲類格式化說明符轉換六正則表達式網上教程學七掃描輸入新增了類。 一、不可變String String類型的對象是不可變的,所有的改變實際上都是創建了一個新的String對象,另外當String作為傳入參數的時候,其實實際上傳入的是這個引用的一個拷貝,這個方法結束了之后這個傳入的引用也就消失了,原來的那個String不會受到方法內的影響而...
摘要:而這可以通過注解辦到,在代碼中以指令語言的形式化方法來為代碼提供更多信息。有注解的說明這個成員變量是一個列名,然后根據注解信息來生成相應的語句。也就是說把注解信息提取了出來。 注解是向代碼中添加信息的一種方法,并且在之后還可以使用這些數據就比如這個方法是用來剝香蕉的,但是我們看就是一串代碼,我們沒辦法在代碼里寫一段指令說我這個程序是用來剝香蕉的,當然除了注釋。而這可以通過注解辦到,在代...
摘要:異常處理程序拋出的異常必須在異常處理程序中得到處理。終止與恢復異常處理有兩種模型,支持終止模型,一旦異常被拋出,表明錯誤無法挽回,無法退回來繼續執行之前出錯的代碼。對于異常來說,最重要的部分就是類名。 一、概念 使用異常能降低處理錯誤代碼的復雜程度,并且將錯誤在一個地方進行處理,于是將描述在正常行為過程中做過什么事的代碼和出了問題怎么辦的代碼相分離 二、基本異常 異常情形指的是當前環境...
摘要:但如果導出類還有抽象方法,那這個類還應該加上聲明為抽象類。并且接口具有繼承的一系列特點,如向上轉型等等。接口中的方法是自動是的。 Thinking in Java 好書全是干貨 一、抽象類和抽象方法 抽象方法:這種方法只有聲明而沒有方法體,下面是抽象方法生命所采用的語法 abstract void f(); 包含抽象方法的類叫做抽象類,如果一個類包含一個或多個抽象方法,該類必須被限定為...
閱讀 1414·2021-11-22 09:34
閱讀 1384·2021-09-22 14:57
閱讀 3417·2021-09-10 10:50
閱讀 1398·2019-08-30 15:54
閱讀 3697·2019-08-29 17:02
閱讀 3479·2019-08-29 12:54
閱讀 2621·2019-08-27 10:57
閱讀 3325·2019-08-26 12:24