類與對象

Java識別對象方式

  • RTTI:編譯時就知道所有類型
  • 反射:運行時發現和使用類信息
    ps:RTTI工作是由Class對象完成,包含了與類有關的信息。

多態相關概念

讓代碼只操作基類的引用,如果添加新派生類,不會影響原有代碼。

類加載

首先檢查類的class對象是否已加載,如果未加載,就會根據類名查找.class,如果已加載,則接受驗證,以保證其未被破壞。
static代碼塊,在類被加載時運行:1. Class.forName 2. new

Class對象

每個類都有一個Class對象。
Java提供一種方法生產隊Class對象的引用,稱爲類字面常量。可用於普通類、接口、數組、基本數據類型。
在使用.class創建對Class對象的引用時,不會自動初始化該class對象,初始化被延遲到了對靜態方法,或非常數靜態域的首次引用,除非使用Class.forName。
Class引用總指向某個Class對象,它可以創造實例,幷包含作用於這些實例的所有方法代碼。

常用方法

xxx instanceOf XXX:用於判斷類型
Class.newInstance:用於創建對象
Class.isInstance:用於判斷類型

equals和hashCode

  • equals
    Object的equals是根據地址進行對比,Double、Integer、String等都覆蓋了equals方法,使equals表示爲比較兩元素是否相等。
    具有的特點:
    1. 自反性
    2. 對稱性
    3. 傳遞性
    4. 一致性
  • hashCode
    方法給對象返回一個hash code值。這個方法被用於hash tables,例如HashMap。
    具有的性質:
    1. 在一個Java應用的執行期間,如果一個對象提供給equals做比較的信息沒有被修改的話,該對象多次調用hashCode()方法,該方法必須始終如一返回同一個integer。
    2. 如果兩個對象根據equals(Object)方法是相等的,那麼調用二者各自的hashCode()方法必須產生同一個integer結果。
    3. equals(java.lang.Object)方法不相等的兩個對象,hashCode()方法必須產生不同的integer結果。
  • PS: 重點
    1. equals相等,hashCode也相等。
    2. 重寫equals時,也需要重寫hashCode。
    3. hashCode相等,equals不一定相等。、
    4. 集合中判斷是否相等先判斷hashCode,再判斷equals,重寫hashCode可改變效率。
// String 的hashCode方法
public int hashCode() {  
    int h = hash;  
    if (h == 0) {  
        int off = offset;  
        char val[] = value;  
        int len = count;  

        for (int i = 0; i < len; i++) {  
            h = 31 * h + val[off++];  
        }  
        hash = h;  
    }  
    return h;  
}

代理模式的應用

主要介紹java的動態代理,實現InvocationHandler

public interface Service {  
    // 代理的方法 
    public abstract void add();  
} 

public class ServiceImpl implements Service {  
    public void add() {  
        System.out.println("This is add service");  
    }  
}

class MyInvocatioHandler implements InvocationHandler {
    private Object target;

    public MyInvocatioHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("-----before-----");
        Object result = method.invoke(target, args);
        System.out.println("-----end-----");
        return result;
    }
}

// 使用動態代理
public class ProxyTest {
    public static void main(String[] args) {
        Service service = new UserServiceImpl();
        // 生成代理對象
        MyInvocatioHandler handler = new MyInvocatioHandler(service);
        Service serviceProxy = (Service)Proxy.newProxyInstance(Service.class.getClassLoader(), new Class[]{Service.class}, new MyInvocatioHandler(service));
        // 使用代理方法
        serviceProxy.add();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章