摘要:通過運(yùn)行時(shí)類型信息,程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對(duì)象的實(shí)際派生類型。編程應(yīng)該盡量面向接口編程,應(yīng)該對(duì)類型信息盡量的少了解二對(duì)象看書,書上寫得好靜態(tài)語句塊在這個(gè)類被加載的時(shí)候運(yùn)行。
一、為什么需要RTTI
Run-Time Type Information。通過運(yùn)行時(shí)類型信息,程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對(duì)象的實(shí)際派生類型。
編程應(yīng)該盡量面向接口編程,應(yīng)該對(duì)類型信息盡量的少了解
package tij.classinfomation;
import java.util.Arrays;
import java.util.List;
public class Test {
public static void main(String[] args) {
List 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";
}
}
二、Class對(duì)象
看書,書上寫得好
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 {
Class clazz = 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");
}
}
靜態(tài)語句塊在這個(gè)類被加載的時(shí)候運(yùn)行。
其中Class.forName方法中要寫類的絕對(duì)路徑,包名+類名,同時(shí)調(diào)用Gum.class.getName的時(shí)候,也并沒有加載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();
}
}
雖然調(diào)用的事jj.showt,但是并沒有加載jj這個(gè)類,而是加載了tt這個(gè)類。
所以就驗(yàn)證了,運(yùn)行時(shí)是實(shí)際用誰了,才加載誰
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;
基本類型也可以用的,這個(gè)方法不會(huì)自動(dòng)初始化這個(gè)類對(duì)象
要使用類的話,要進(jìn)行三個(gè)步驟
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;
這是錯(cuò)的
Class extends Number> genericIntClass = Integer.class;
這個(gè)可以
Class> genericIntClass = Integer.class;
有個(gè)>比class光桿優(yōu)雅
package tij.classinfomation;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
FilledList fl = 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類”
這兩個(gè)是有區(qū)別的
沒啥卵用= =就是類型裝換嘛
三、類型轉(zhuǎn)換前先做檢查看書吧= =這段太費(fèi)勁了。
四、注冊(cè)工廠要在已有的繼承關(guān)系中添加新的繼承關(guān)系,最合適的就是應(yīng)該將新添加的類再父類中完成注冊(cè)。
結(jié)合工廠設(shè)計(jì)模式
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類中新添加一個(gè)add就可以完成注冊(cè)了。
另外此處運(yùn)用到了工廠方法,往列表里添加的也是一個(gè)工廠對(duì)象,這樣的意義在于將創(chuàng)建對(duì)象的任務(wù)交給各個(gè)對(duì)象自己的工廠來辦,利用多態(tài)的性質(zhì),在新添加的類中相似實(shí)現(xiàn)工廠可以達(dá)到生成新的子類的對(duì)象的目的。
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);
}
}
六、反射:運(yùn)行時(shí)的類信息
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(""));
}
}
}
七、動(dòng)態(tài)代理
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那邊這里講的就很好。
八、空對(duì)象沒懂= =
end
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.hztianpu.com/yun/67589.html
摘要:迭代器解決了這個(gè)問題。刪除后于是我們可以寫一個(gè)方法,接受一個(gè)類型,然后讓他調(diào)用方法,這就不需要考慮這個(gè)是個(gè)還是了,也就是說,可以將遍歷容器的操作與序列底層的結(jié)構(gòu)分離,迭代器統(tǒng)一了對(duì)容器類的訪問方式。十二和兩種遍歷的方法,與迭代器方法。 一、泛型和類型安全的容器 package tij.hoding; import java.util.ArrayList; public class ...
摘要:四上的操作看五格式化輸出運(yùn)用和語言很相似和是等價(jià)的喲類格式化說明符轉(zhuǎn)換六正則表達(dá)式網(wǎng)上教程學(xué)七掃描輸入新增了類。 一、不可變String String類型的對(duì)象是不可變的,所有的改變實(shí)際上都是創(chuàng)建了一個(gè)新的String對(duì)象,另外當(dāng)String作為傳入?yún)?shù)的時(shí)候,其實(shí)實(shí)際上傳入的是這個(gè)引用的一個(gè)拷貝,這個(gè)方法結(jié)束了之后這個(gè)傳入的引用也就消失了,原來的那個(gè)String不會(huì)受到方法內(nèi)的影響而...
摘要:而這可以通過注解辦到,在代碼中以指令語言的形式化方法來為代碼提供更多信息。有注解的說明這個(gè)成員變量是一個(gè)列名,然后根據(jù)注解信息來生成相應(yīng)的語句。也就是說把注解信息提取了出來。 注解是向代碼中添加信息的一種方法,并且在之后還可以使用這些數(shù)據(jù)就比如這個(gè)方法是用來剝香蕉的,但是我們看就是一串代碼,我們沒辦法在代碼里寫一段指令說我這個(gè)程序是用來剝香蕉的,當(dāng)然除了注釋。而這可以通過注解辦到,在代...
摘要:異常處理程序拋出的異常必須在異常處理程序中得到處理。終止與恢復(fù)異常處理有兩種模型,支持終止模型,一旦異常被拋出,表明錯(cuò)誤無法挽回,無法退回來繼續(xù)執(zhí)行之前出錯(cuò)的代碼。對(duì)于異常來說,最重要的部分就是類名。 一、概念 使用異常能降低處理錯(cuò)誤代碼的復(fù)雜程度,并且將錯(cuò)誤在一個(gè)地方進(jìn)行處理,于是將描述在正常行為過程中做過什么事的代碼和出了問題怎么辦的代碼相分離 二、基本異常 異常情形指的是當(dāng)前環(huán)境...
摘要:但如果導(dǎo)出類還有抽象方法,那這個(gè)類還應(yīng)該加上聲明為抽象類。并且接口具有繼承的一系列特點(diǎn),如向上轉(zhuǎn)型等等。接口中的方法是自動(dòng)是的。 Thinking in Java 好書全是干貨 一、抽象類和抽象方法 抽象方法:這種方法只有聲明而沒有方法體,下面是抽象方法生命所采用的語法 abstract void f(); 包含抽象方法的類叫做抽象類,如果一個(gè)類包含一個(gè)或多個(gè)抽象方法,該類必須被限定為...
閱讀 1662·2021-11-22 09:34
閱讀 1538·2021-09-22 14:57
閱讀 3600·2021-09-10 10:50
閱讀 1651·2019-08-30 15:54
閱讀 3826·2019-08-29 17:02
閱讀 3609·2019-08-29 12:54
閱讀 2774·2019-08-27 10:57
閱讀 3456·2019-08-26 12:24