Java學習筆記(三)

**

反射的原理,Class.forName和ClassLoader區別,反射創建類實例的三種方式

Java在編譯的時候生成了一個 .class文件,反射就是通過尋找該文件裏的字節碼找到對應的類、方法、屬性。
Class.forName和ClassLoader區別在於前者加載類需要初始化後者不會只是將其加載到了jvm虛擬機中

public class testReflex {
	public static void main(String args[]){
		
		Person p1=new Person("小明" ,20,'男' );
		Person p2=new Person("小紅",22,'女');
		//第一種getClass()
		Class class1=p1.getClass();
		System. out.println(p1.getClass().getName());
		try {
			Field f=p1.getClass().getDeclaredField("name");
			f.setAccessible(true);
			f.set(p1, "阿狗");
			System. out.println(p1.getName());
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Class class2 = p2.getClass();
		System. out.println(class1 == class2 );//true
		//第二種利用class屬性
		Class class3=Person.class;
		System. out.println(class1 == class3 );//true

		Class class4=null;
		try {
		//第三種forName()
			class4=Class.forName("test.Person");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(class4==class1);//true
	}
}

**
**

final的用途

作用於變量若變量爲基本類型則不可修改,若變量爲引用則可以改變其指向的內容不能改變其指向(即地址不能改地址上存的值能改)
作用於參數與變量一致
作用於方法把方法鎖定,以防任何繼承類修改它的含義,即該方法不會被繼承的類覆蓋只能被繼承
作用於類該類不可被繼承
**
**

Jdk動態代理

jdk動態代理利用反射的機制不過只能代理接口委託類必須實現某個或者某些接口
接口類

package test;

public interface People{
	
	public void sayHello();
}

實現類

package test;

public class Chinese implements People {
	@Override
  public void sayHello(){
	  
	  System.out.println("Chinese say hello");
  }
}

代理實現類

package test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class PeopleInvocationHandler implements InvocationHandler {
	private Object people;
	PeopleInvocationHandler(Object people){		
		this.people=people;
	}
	@Override
	public Object invoke(Object proxy,Method method,Object args[])
	throws Throwable{
		//委託給sun.reflect.MethodAccessor來處理反射
		Object invoke=method.invoke(people, args);
		System.out.println("---end---");
		return invoke;
		
	}
}

測試類

package test;
import java.lang.reflect.Proxy;
public class testproxy {
	public static void main(String args[]){
		//子類向上轉型
		People chinese=new Chinese();
		PeopleInvocationHandler invohandler=new PeopleInvocationHandler(chinese);
		//只能傳接口
		People proxy= (People)Proxy.newProxyInstance(chinese.getClass().getClassLoader(),chinese.getClass().getInterfaces(),invohandler);
		proxy.sayHello();
	}
}

Cglib動態代理本質也是通過反射不過是利用繼承關係,利用asm在運行時動態生成委託類的子類,從而實現對委託類的代理。因此不依賴接口。所以不能代理final修飾的類
測試類

package test;

public class cglibchinese {
	public void sayHello(){
		  
		  System.out.println("Chinese say hello");
	  }
	public void saysb(){
		  
		  System.out.println("Chinese say hello sb");
	  }

}

代理生成類

package test;
import java.lang.reflect.Method;
import java.lang.Object;
import org.springframework.cglib.proxy.*;//用了spring-core-4.xx以上的版本
public class ChineseProxy implements MethodInterceptor{
	@Override
	public Object intercept(Object object,Method method,Object[] args,MethodProxy methodProxy) throws Throwable{
	 Object intercept=methodProxy.invokeSuper(object,args);
	 System.out.println("spcs");
	 return intercept;
 }
 
}

代理測試類

package test;
import org.springframework.cglib.proxy.*;

public class testcglib {
	public static void main(String args[]){
		
		ChineseProxy chineseproxy=new ChineseProxy();
		Enhancer enhancer=new Enhancer();
		//enhancer.setSuperclass(Chinese.class);
		enhancer.setSuperclass(cglibchinese.class);
		enhancer.setCallback(chineseproxy);
		
		//People proxy=(People)enhancer.create();代理接口利用向上轉型
		cglibchinese proxy=(cglibchinese)enhancer.create();
		proxy.sayHello();
	}

}

**
**

在父類中爲子類自動完成所有的 hashcode 和 equals 實現

優點可以添加自定義邏輯,且不必調用超類的實現。
缺點容易出問題尤其是在子類覆蓋equals方法沒覆蓋hashcode時可能降低散列表性能,或者相同對象不同hashcode
**

發佈了35 篇原創文章 · 獲贊 30 · 訪問量 2292
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章