国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java基礎(chǔ)提高

JasinYip / 1126人閱讀

摘要:獲得對象的方法有三種判定指定的對象是否表示一個(gè)基本類型。接下來給出的是與其它類相比而言獨(dú)一無二的特征提供一個(gè)默認(rèn)的無參構(gòu)造函數(shù)。返回對象,表示聲明此類型的類或接口。

這是傳智張孝祥老師Java高新技術(shù)的授課筆記
我認(rèn)為講的很棒,授課傳送門如下:
Java高新技術(shù)

一、枚舉 1.基本應(yīng)用
public class Test {
    public static void main(String[] args) {
        WeekDay day1=WeekDay.FRI;
        System.out.println(day1.name());
        System.out.println(day1.ordinal());
        System.out.println(WeekDay.valueOf("SUN"));
    }
}
enum WeekDay{
    SUN,MON,TUE,WED,THU,FRI,SAT;
}
2.帶有構(gòu)造方法的枚舉
public class Test {
    public static void main(String[] args) {
        WeekDay day1=WeekDay.FRI;
        System.out.println(day1.name());
        System.out.println(day1.ordinal());
        System.out.println(WeekDay.valueOf("SUN"));
    }
}
enum WeekDay{
    SUN(1),MON,TUE,WED,THU,FRI,SAT;
    private WeekDay(){//枚舉類的靜態(tài)變量在枚舉被加載的時(shí)候就會(huì)創(chuàng)建,并且只能用私有修飾
        System.out.println("none parameter");
    }
    private WeekDay(int i){
        System.out.println("parameter:"+i);
    }
}
3.帶有抽象方法的枚舉
public class Test {
    public static void main(String[] args) {
    }
}

enum TrafficLamp{
    RED(30) {
        @Override
        TrafficLamp nextLamp() {
            return GREEN;
        }
    },GREEN(45) {
        @Override
        TrafficLamp nextLamp() {
            return YELLOW;
        }
    },YELLOW(5) {
        @Override
        TrafficLamp nextLamp() {
            return RED;
        }
    };
    abstract TrafficLamp nextLamp();
    private int time;
    private TrafficLamp(int time){
        this.time=time;
    }
}
二、反射 1.Class類

在Java中,每個(gè)class都有一個(gè)相應(yīng)的Class對象。也就是說,當(dāng)我們編寫一個(gè)類,編譯完成后,在生成的.class文件中,就會(huì)產(chǎn)生一個(gè)Class對象,用于表示這個(gè)類的類型信息。
獲得class對象的方法有三種

        Class c1=Date.class;
        Class c2=new Date().getClass();
        Class c3=Class.forName("java.util.Date");
        System.out.println(c1==c2);
        System.out.println(c1==c3);

public boolean isPrimitive()判定指定的 Class 對象是否表示一個(gè)基本類型。
有九種預(yù)定義的 Class 對象,表示八個(gè)基本類型和 void。這些類對象由 Java 虛擬機(jī)創(chuàng)建,與其表示的基本類型同名,即 boolean、byte、char、short、int、long、float 和 double。 這些對象僅能通過下列聲明為 public static final 的變量訪問,也是使此方法返回 true 的僅有的幾個(gè) Class 對象。

public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        Class c1=Date.class;
        Class c2=int.class;
        Class c3=Integer.class;
        Class c4=Integer.TYPE;
        System.out.println(c1.isPrimitive());
        System.out.println(c2.isPrimitive());
        System.out.println(c3.isPrimitive());
        System.out.println(c4.isPrimitive());
        System.out.println(c2==c3);
        System.out.println(c2==c4);
        
        Class c5=int[].class;
        System.out.println(c5.isPrimitive());
        System.out.println(c5.isArray());
    }
}
2.反射

反射就是把類中的各種成分映射成相應(yīng)的類,比如把“方法”映射成Method類,把“成員變量”映射成Field類等等

2.1 構(gòu)造方法的反射應(yīng)用

public class Test {
    public static void main(String[] args) throws Exception{
        Constructor constructor1=String.class.getConstructor(StringBuffer.class);//要是用類型
        String str2=(String)constructor1.newInstance(new StringBuffer("abc"));//要使用之前類型相同的對象
        System.out.println(str2);
        String str2=(String)Class.forName("java.lang.String").newInstance();//使用默認(rèn)的構(gòu)造方法
    }
}

2.2 成員變量的反射應(yīng)用

“人有身高這一屬性”與“我有身高這一屬性不同”,也與“我的身高是XXX”不同

public class Test {
    public static void main(String[] args) throws Exception{
        Person me=new Person(180,140);
        Field height_field=Person.class.getField("height");
        //height_field指的是取得了Person這個(gè)類所具有的一個(gè)屬性,即身高這樣一個(gè)屬性,并不是取得的某個(gè)人的實(shí)際身高
        System.out.println(height_field.get(me));
        Field weight_field=Person.class.getDeclaredField("weight");
        weight_field.setAccessible(true);
        System.out.println(weight_field.get(me));
    }
}

class Person{
    public int height;
    private int weight;
    public Person(int height, int weight) {
        super();
        this.height = height;
        this.weight = weight;
    }
}

修改某一對象中的成員變量舉例:

import java.lang.reflect.Field;

public class Test {
    public static void main(String[] args) throws Exception{
        ReflectPoint pt1=new ReflectPoint(3,5);
        Field[] fields=ReflectPoint.class.getFields();
        for (Field field : fields) {
            if(field.getType()==String.class){
                String oldValue=(String)field.get(pt1);
                String newValue=oldValue.replace("b", "a");
                field.set(pt1, newValue);
            }
        }
        System.out.println(pt1);
    }
}


class ReflectPoint{
    public ReflectPoint(int x, int y) {
        super();
        this.x = x;
        this.y = y;
    }
    private int x;
    public int y;
    public String str1="ball";
    public String str2="basketball";
    public String str3="itcast";
    @Override
    public String toString() {
        return "ReflectPoint [x=" + x + ", y=" + y + ", str1=" + str1 + ", str2=" + str2 + ", str3=" + str3 + "]";
    }
}

2.3 成員方法的反射

基本應(yīng)用
“人有跳的能力”與“我有跳的能力”不一樣

public class Test {
    public static void main(String[] args) throws Exception{
        Method methodCharAt=String.class.getMethod("charAt", int.class);//后面指的是傳入的參數(shù)
        //同樣,這取得的是String類的這樣一個(gè)方法,是一種屬性,而不是某個(gè)對象的成員方法
        System.out.println(methodCharAt.invoke("abcde", 1));
        
        //someMethod.invoke(null,parameter)指的是調(diào)用的靜態(tài)方法
    }
}

應(yīng)用:
目標(biāo):寫一個(gè)程序,這個(gè)程序能夠根據(jù)用戶提供的類名,去調(diào)用類方法

import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws Exception{
        
//        TestArguments.main(new String[]{"111","222","333"});
        
        String startingClassName=args[0];
        Method mainMethod=Class.forName(startingClassName).getMethod("main", String[].class);
        mainMethod.invoke(null, (Object)new String[]{"111","222","333"});
        /* 如果沒有類型轉(zhuǎn)換會(huì)出現(xiàn)problems
         * Type String[] of the last argument to method invoke(Object, Object...) 
         * doesn"t exactly match the vararg parameter type. Cast to Object[] to confirm the non-varargs invocation,
         * or pass individual arguments of type Object for a varargs invocation.
        */
    }
}


class TestArguments{
    public static void main(String[] args) {
        for (String string : args) {
            System.out.println(string);
        }
    }
}

要修改run configuration

2.4 數(shù)組與Object的關(guān)系及其反射類型
維度與類型同時(shí)相同時(shí),得到的class即相同

public class Test {
    public static void main(String[] args) throws Exception{
        int[] a0=new int[3];
        int[] a1=new int[3];
        int[] a2=new int[4];
        System.out.println(a0.getClass()==a1.getClass());
        System.out.println(a1.getClass()==a2.getClass());
        System.out.println(a1.getClass().getName());
    }
}

2.5 數(shù)組的反射應(yīng)用
舉例

public class Test {
    public static void main(String[] args) throws Exception{
        
        printObject(new String[]{"a","b","c"});
        printObject("xyz");
    }

    private static void printObject(Object obj) {
        Class c=obj.getClass();
        if(c.isArray()){
            int len=Array.getLength(obj);
            for(int i=0;i

2.6 ArrayList_HashSet的比較及Hashcode分析

先比較hashcode如果hashcode相同,則運(yùn)行equels方法,兩者同時(shí)相等時(shí),則認(rèn)定為相同對象,如果之后修改了參與運(yùn)算hashcode的成員變量,則會(huì)造成內(nèi)存溢出,如下例子中remove會(huì)失效

import java.util.HashSet;

public class Test {
    public static void main(String[] args) throws Exception{
        HashSet set=new HashSet<>();
        TestArguments t1=new TestArguments(3);
        TestArguments t2=new TestArguments(3);
        set.add(t1);
        set.add(t2);
        System.out.println(set.size());
        t1.x=456;
        set.remove(t1);
        System.out.println(set.size());
    }

}


class TestArguments{
    int x;

    public TestArguments(int x) {
        super();
        this.x = x;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + x;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        TestArguments other = (TestArguments) obj;
        if (x != other.x)
            return false;
        return true;
    }
    
}
3.反射的作用——實(shí)現(xiàn)框架功能

框架
現(xiàn)在使用別人寫的類的時(shí)候,有兩種使用方式,一種是用戶去使用別人的類(工具),另一種是別人的類去調(diào)用用戶寫的類(框架)。再打個(gè)比方:比如我做房子賣給用戶居住,由用戶自己安裝門窗和空調(diào),我制作的房子就是框架,用戶需要使用我的框架,把門窗插入進(jìn)我提供的框架之中,即用戶的門窗被房子調(diào)用,這就是框架。

框架要解決的核心問題
在寫框架的時(shí)候并不知道用戶要寫的類名,所以框架中不能直接new某個(gè)類的實(shí)例對象,因此只能通過反射來做

代碼舉例

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.Properties;

public class Test {
    public static void main(String[] args) throws Exception{
        
        InputStream ips=new FileInputStream("config.properties");
        Properties props=new Properties();
        props.load(ips);
        ips.close();
        String className=props.getProperty("className");
        @SuppressWarnings("unchecked")
        Collection collection=(Collection)Class.forName(className).newInstance();
        
        ReflectPoint pt1=new ReflectPoint(3,3);
        ReflectPoint pt2=new ReflectPoint(5,5);
        ReflectPoint pt3=new ReflectPoint(3,3);
        
        collection.add(pt1);
        collection.add(pt2);
        collection.add(pt3);
        
        System.out.println(collection.size());
    }

}

config.properties文件內(nèi)容為

className=java.util.ArrayList

3.1 管理配置文件的方式

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.Properties;

public class Test {
    public static void main(String[] args) throws Exception{
//        InputStream ips=new FileInputStream("config.properties");
        
        //以下的配置文件路徑應(yīng)該與該類的Java文件放在同一目錄
//        InputStream ips=ReflectPoint.class.getResourceAsStream("config.properties");
        InputStream ips=ReflectPoint.class.getClassLoader().getResourceAsStream("zheteng/config.properties");
        Properties props=new Properties();//此方法首先搜索資源的父類加載器;如果父類加載器為 null,則搜索的路徑就是虛擬機(jī)的內(nèi)置類加載器的路徑。
        props.load(ips);
        ips.close();
        String className=props.getProperty("className");
        @SuppressWarnings("unchecked")
        Collection collection=(Collection)Class.forName(className).newInstance();
        
        ReflectPoint pt1=new ReflectPoint(3,3);
        ReflectPoint pt2=new ReflectPoint(5,5);
        ReflectPoint pt3=new ReflectPoint(3,3);
        
        collection.add(pt1);
        collection.add(pt2);
        collection.add(pt3);
        
        System.out.println(collection.size());
    }

}



class ReflectPoint{
    public ReflectPoint(int x, int y) {
        super();
        this.x = x;
        this.y = y;
    }
    private int x;
    public int y;
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + x;
        result = prime * result + y;
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ReflectPoint other = (ReflectPoint) obj;
        if (x != other.x)
            return false;
        if (y != other.y)
            return false;
        return true;
    }
}
4.JavaBean

JavaBean是特殊的Java類,使用Java語言書寫,并且遵守JavaBean API規(guī)范。
接下來給出的是JavaBean與其它Java類相比而言獨(dú)一無二的特征:

提供一個(gè)默認(rèn)的無參構(gòu)造函數(shù)。

需要被序列化并且實(shí)現(xiàn)了Serializable接口。

可能有一系列可讀寫屬性。

可能有一系列的"getter"或"setter"方法。

Java bean 是個(gè)什么概念? - 回答作者: 楊博 通俗易懂

我認(rèn)為,JavaBean的存在就是為了讓類中的屬性能更方便地被處理和提取

4.1 JavaBean的簡單操作

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws Exception {
        ReflectPoint pt1 = new ReflectPoint(3, 5);
        String propertyName = "x";
        PropertyDescriptor pd = new PropertyDescriptor(propertyName, ReflectPoint.class);
        Method methodGetX = pd.getReadMethod();
        Object retVal = methodGetX.invoke(pt1);
        System.out.println(retVal);

        Method methodSetX = pd.getWriteMethod();
        methodSetX.invoke(pt1, 7);
        System.out.println(pt1.getX());
    }

}

class ReflectPoint {
    public ReflectPoint(int x, int y) {
        super();
        this.x = x;
        this.y = y;
    }

    private int x;
    private int y;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

}

4.2 BeanUtils工具包操作JavaBean
需要BeanUtils與common.logging包

舉例1:

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;

public class Test {
    public static void main(String[] args) throws Exception {
        ReflectPoint pt1 = new ReflectPoint(3, 5);
        
        
        System.out.println(BeanUtils.getProperty(pt1, "x"));
        System.out.println(BeanUtils.getProperty(pt1, "x").getClass().getName());
        BeanUtils.setProperty(pt1, "x", "9");//以string的形式對javabean進(jìn)行操作
        System.out.println(pt1.getX());
        
        BeanUtils.setProperty(pt1, "birthday.time", 111);
        System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));
        
        
        PropertyUtils.setProperty(pt1, "x", 9);//以屬性本身的類型的形式對javabean進(jìn)行操作
        System.out.println(PropertyUtils.getProperty(pt1, "x").getClass().getName());
    }
}

其中ReflectPoint為

import java.util.Date;

public class ReflectPoint {
    public ReflectPoint(int x, int y) {
        super();
        this.x = x;
        this.y = y;
        this.birthday = new Date();
    }

    private int x;
    private int y;
    private Date birthday;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

}
三、注解 1.了解注解

1.1 @Deprecated

public class AnnotationTest {
    public static void main(String[] args) {
        sayHello();
    }
    
    @Deprecated
    public static void sayHello(){
        System.out.println("hello!SF.GG!");
    }
    
}

1.2 @Override

@Override
    public String toString() {
        return "AnnotationTest []";
    }
2.注解的定義與反射調(diào)用
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@MyAnnotation
public class AnnotationTest {
    
    public static void main(String[] args) {
        sayHello();
        
        if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)){
            MyAnnotation myannotation=(MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
            System.out.println(myannotation);
        }
            
        
    }
    
    @Deprecated
    public static void sayHello(){
        System.out.println("hello!SF.GG!");
    }

    
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
@interface MyAnnotation{
    
}
3.為注解增加各種屬性

看起來注解就是為了方便為自定義的類打上一些標(biāo)簽的作用

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@MyAnnotation(color = "red", value = "abc", arrayValue = 1,annotationAttr=@MetaAnnotation("flx"))
public class AnnotationTest {

    @MyAnnotation("xyz") // 當(dāng)只有一個(gè)value屬性需要賦值的時(shí)候,可以不用寫value
    public static void main(String[] args) {
        sayHello();

        if (AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation myannotation = (MyAnnotation) AnnotationTest.class.getAnnotation(MyAnnotation.class);
            System.out.println(myannotation.color());
            System.out.println(myannotation.value());
            System.out.println(myannotation.arrayValue().length);
            System.out.println(myannotation.trafficLamp().next());
            System.out.println(myannotation.annotationAttr().value());
        }

    }

    @Deprecated
    public static void sayHello() {
        System.out.println("hello!SF.GG!");
    }

}

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@interface MyAnnotation {
    String color() default "blue";

    String value();

    int[] arrayValue() default { 3, 4, 4 };

    Lamp trafficLamp() default Lamp.RED;

    MetaAnnotation annotationAttr() default @MetaAnnotation("lhm");
}

@interface MetaAnnotation {
    String value();
}

enum Lamp {
    RED, YELLOW, GREEN;
    Lamp next() {
        if (this.equals(RED)) {
            return GREEN;
        }
        if (this.equals(GREEN)) {
            return YELLOW;
        } else {
            return RED;
        }
    }
}
四、泛型 1.基本應(yīng)用
import java.lang.reflect.Constructor;
import java.util.ArrayList;

public class Test {
    public static void main(String[] args) throws Exception {
        ArrayList collection1=new ArrayList<>();
        collection1.add(1);
        collection1.add(1L);
        collection1.add("abc");
        int i=(Integer) collection1.get(0);
        System.out.println(collection1.get(0) instanceof Integer);
        
        Constructor constructer1=String.class.getConstructor(String.class);
        String str=constructer1.newInstance("abc");
        System.out.println(str);
    
    }
}
2.內(nèi)部原理

2.1.泛型是給編譯器使用的,可以在限定集合中輸入類型,讓編譯器擋住源程序中的非法輸入,編譯器編譯生成的字節(jié)碼會(huì)去掉方形的類型信息的,如下所示

import java.util.ArrayList;

public class Test {
    public static void main(String[] args) throws Exception {
        ArrayList collection2 = new ArrayList<>();
        ArrayList collection3 = new ArrayList<>();

        System.out.println(collection2.getClass() == collection3.getClass());

    }
}

也因此,如下代碼并不是重載,是錯(cuò)誤的,因?yàn)檫\(yùn)行時(shí)會(huì)去泛型信息

    public static void applyVector(Vector v1){
        
    }
    
    public static void applyVector(Vector v1){
        
    }

就是說泛型只是給編譯器看的,運(yùn)行的時(shí)候就沒有泛型信息了,也因此可以根據(jù)這種原理,以反射的原理得到集合再調(diào)用add方法,比如往上面collection3里添加String

import java.util.ArrayList;

public class Test {
    public static void main(String[] args) throws Exception {
        ArrayList collection2 = new ArrayList<>();
        ArrayList collection3 = new ArrayList<>();

        System.out.println(collection2.getClass() == collection3.getClass());
        
//        collection3.add("abc");
//        報(bào)錯(cuò)
        collection3.getClass().getMethod("add", Object.class).invoke(collection3, 1);
        collection3.getClass().getMethod("add", Object.class).invoke(collection3, "abc");
        System.out.println(collection3); 
    }
}

2.2 語法規(guī)定

ArrayList稱為泛型類型,E稱為類型變量或類型參數(shù),<>做typeof

參數(shù)化類型不考慮類型參數(shù)的繼承關(guān)系,下面兩個(gè)都是錯(cuò)誤的

   ArrayList c=new ArrayList();
   ArrayList b=new ArrayList();

參數(shù)化和原始類型的兼容性,下面例子中C只能裝string,而b可以加object,其實(shí)b那種寫法和ArrayList b=new ArrayList()是一樣的,因?yàn)榉盒椭皇墙o編譯器看的

   ArrayList c=new ArrayList();
   c.add("asdf");
   System.out.println(c.get(0).getClass());
   ArrayList b=new ArrayList();
   b.add(456);
   b.add("asdf");
   System.out.println(b.get(0).getClass());
   System.out.println(b.get(1).getClass());

下面不報(bào)錯(cuò)的

   ArrayList b=new ArrayList();
   ArrayList d=b;

2.3 泛型通配符
比如現(xiàn)在要打印一個(gè)類型參數(shù)是任意類型的集合,如下寫法就是不對的

import java.util.ArrayList;
import java.util.Collection;

public class Test {
    public static void main(String[] args) throws Exception {
        ArrayList collection2 = new ArrayList<>();
        ArrayList collection3 = new ArrayList<>();
        System.out.println(collection3); 
        printCollection(collection3);//編譯器不通過,因?yàn)橹罢f過,泛型類型并不存在類型參數(shù)的繼承關(guān)系
        
    }
    
    public static void printCollection(Collection collection){
        
    }
    
}

這就需要通配符了

import java.util.ArrayList;
import java.util.Collection;

public class Test {
    public static void main(String[] args) throws Exception {
        ArrayList collection2 = new ArrayList<>();
        ArrayList collection3 = new ArrayList<>();
        System.out.println(collection3); 
        printCollection(collection3);//編譯器不通過,因?yàn)橹罢f過,泛型類型并不存在類型參數(shù)的繼承關(guān)系
        
    }
    
    public static void printCollection(Collection collection){
//        collection.add(123);
//        會(huì)報(bào)錯(cuò),因?yàn)槭褂昧送ㄅ浞虼瞬荒苷{(diào)用與類型參數(shù)相關(guān)的方法        
//        參數(shù)(int)不適用于Collection 類型的add(capture#1-of?)方法,
        collection.size();//這就沒錯(cuò),因?yàn)閟ize方法與類型參數(shù)沒有關(guān)系
        for (Object object : collection) {
            System.out.println(object);
        }
    }
}

使用?通配符可以引用各種參數(shù)類型,其主要作用是引用,而不是寫入
通配符也有拓展功能

限定上邊界
? extends Number要求傳入的必須是Number的子類

限定下邊界
? super Integer要求傳入的必須是Integer的父類

3.自定義泛型

3.1 泛型方法

public class Test {
    public static void main(String[] args) throws Exception {

        //結(jié)果就是二者的交集
        Number num=add(3,51.0);
        Integer inte=add(3,51);
        Object o=add(3,"123");
        
        swap(new String[]{"aaa","bbb","ccc"},1,2);
//        swap(new int[]{123,456,789},1,2);//泛型變量只能是引用對象,int[]已經(jīng)是一個(gè)基本類型的數(shù)組,它并不能完成自動(dòng)裝箱
    }
    
    private static  T add(T x,T y){
        return null;
    }
    
    private static  void swap(T[] a,int i,int j){
        T temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }
    
    private static  void sayHello() throws T{
        try{
            
        }catch(Exception e){//必須明確是哪個(gè)異常,不能catch T
            throw (T)e;
        }
    }
}

3.2 在類上定義泛型

就是為了保障類中的泛型能夠統(tǒng)一,為此可以在類上定義泛型

public class Test {
    public static void main(String[] args) throws Exception {
        GenericDao dao=new GenericDao<>();
        
        dao.add("123");
    }
    
}


class GenericDao{
    public void add(T x){
        
    }
    
    public T getByID(int id){
        return null;
    }
    
    public void delete(T obj){
        
    }
}

3.3 通過反射獲得泛型的實(shí)際類型參數(shù)

之前說過,泛型是給編譯器看的,因此假如有一個(gè)變量Vector v1,僅僅從v1這個(gè)變量,是沒法知道這個(gè)Vector里的泛型到底是什么的,因此通過其他一種方法獲得,

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.Vector;

public class Test {
    public static void main(String[] args) throws Exception {

        Method applyMethod=Test.class.getMethod("applyVector", Vector.class);
        Type[] types=applyMethod.getGenericParameterTypes();
        /*
         * 按照聲明順序返回 Type 對象的數(shù)組,這些對象描述了此 Method 對象所表示的方法的形參類型的。如果底層方法不帶參數(shù),則返回長度為 0 的數(shù)組。 
         * 如果形參類型是參數(shù)化類型,則為其返回的Type對象必須實(shí)際反映源代碼中使用的實(shí)際類型參數(shù)。 
         * 如果形參類型是類型變量或參數(shù)化類型,則創(chuàng)建它。否則將解析它。 
         */
        ParameterizedType ptype=(ParameterizedType)types[0];
        System.out.println(ptype.getRawType());
        /*
         * 返回 Type 對象,表示聲明此類型的類或接口。 
         */
        System.out.println(ptype.getActualTypeArguments()[0]);
        /*
         * 返回表示此類型實(shí)際類型參數(shù)的 Type 對象的數(shù)組。
         */
    }
    
    public static void applyVector(Vector v1){
        
    }
    
}
五、類加載器 1.類加載器基本概念

要使用這個(gè)類,就要把.class文件加載進(jìn)虛擬機(jī),然后進(jìn)行處理,就需要類加載器,Java虛擬機(jī)中可以安裝多個(gè)類加載器,系統(tǒng)默認(rèn)三個(gè)主要加載器,每個(gè)加載器都加載特定位置的類:BootStrap,ExtClassLoader,AppClassLoader
類加載器本身也是一個(gè)Java類,因此也需要被加載,因此一個(gè)特殊的加載器,即BootStrap,它不是一個(gè)Java類
而Java虛擬機(jī)中所有類加載器采用具有父子關(guān)系的樹形結(jié)構(gòu)進(jìn)行組織,在實(shí)例化每個(gè)類加載器對象之前,需要指定一個(gè)父極類加載器對象

public class Test {
    public static void main(String[] args) throws Exception {
        System.out.println(Test.class.getClassLoader().getClass());
        System.out.println(System.class.getClassLoader());
//        null,說明這是又bootstrap類加載器加載的
        
        ClassLoader loader=Test.class.getClassLoader();
        while(loader!=null){
            System.out.println(loader.getClass());
            loader=loader.getParent();
        }
    }
}
2.委托機(jī)制

(太困了扛不住了)

3.自定義類加載器

首先搞一個(gè)類的加密器,將類文件進(jìn)行二進(jìn)制簡單加密,用生成的類文件覆蓋掉原本的類文件后,再次運(yùn)行程序,發(fā)現(xiàn)類加載錯(cuò)誤

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

public class MyClassLoader {

    public static void main(String[] args) throws Exception {
        String srcPath = "bin/zheteng/ClassLoaderAttachment.class";
        String destPath = "ClassLoaderAttachment.class";
        FileInputStream fis = new FileInputStream(srcPath);
        FileOutputStream fos = new FileOutputStream(destPath);
        cypher(fis,fos);
        fis.close();
        fos.close();
        
        System.out.println(new ClassLoaderAttachment().toString());
        
    }

    private static void cypher(InputStream ips, OutputStream ops) throws Exception {
        int b = -1;
        while ((b = ips.read()) != -1) {
            ops.write(b ^ 0xff);
        }
    }

}

class ClassLoaderAttachment extends Date {
    /**
     * 
     */
    private static final long serialVersionUID = -1118939564631068343L;

    public String toString(){
        return "hello,world";
    }
}

下面再搞一個(gè)解密的類加載器

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

public class MyClassLoader extends ClassLoader {

    public static void main(String[] args) throws Exception {
        String srcPath = "bin/zheteng/ClassLoaderAttachment.class";
        String destPath = "ClassLoaderAttachment.class";
        FileInputStream fis = new FileInputStream(srcPath);
        FileOutputStream fos = new FileOutputStream(destPath);
        cypher(fis, fos);
        fis.close();
        fos.close();

         System.out.println(new ClassLoaderAttachment());

        Class d1 = new MyClassLoader().loadClass("ClassLoaderAttachment.class");
        Date d = (Date) d1.newInstance();

        System.out.println(d.toString());
    }

    private static void cypher(InputStream ips, OutputStream ops) throws Exception {
        int b = -1;
        while ((b = ips.read()) != -1) {
            ops.write(b ^ 0xff);
        }
    }


    @Override
    protected Class findClass(String name) throws ClassNotFoundException {
        String classFileNmae = name;
        try {
            System.out.println(name);
            FileInputStream fis = new FileInputStream(classFileNmae);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            cypher(fis, bos);
            fis.close();
            byte[] bytes = bos.toByteArray();
            return defineClass(bytes, 0, bytes.length);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return super.findClass(name);
    }

    public MyClassLoader() {

    }

}

這次的attachment必須定義為public類否則上面的反射會(huì)異常訪問權(quán)限報(bào)錯(cuò)

import java.util.Date;

public class ClassLoaderAttachment extends Date {
    /**
     * 
     */
    private static final long serialVersionUID = -1118939564631068343L;

    public String toString(){
        return "hello,worldxx";
    }
}

其實(shí)我覺得這塊講的我沒太聽明白,以后看thingking in java的時(shí)候再補(bǔ)上吧

六、代理 1.代理的概念與作用

1.1 代理
要為已存在的具有相同接口的目標(biāo)類的各個(gè)方法添加一套系統(tǒng)功能,如異常處理,日志記錄等,如

class x{
    A
    void sayHello{
        syso:hello;
    }
    B
}

現(xiàn)在想在AB兩點(diǎn)記錄時(shí)間,測試運(yùn)行時(shí)間,而且沒有程序的源代碼,該如何處理
需要定義一個(gè) 新的代理類

XProxy
{
    void sayHello{
        starttime
        syso:hello
        endtime
    }
}

相當(dāng)于用這個(gè)代理來運(yùn)行這個(gè)程序,以完成相應(yīng)的目的,這就是代理的作用。代理類的每個(gè)方法調(diào)用目標(biāo)類的相同方法,并在調(diào)用方法時(shí)加上系統(tǒng)功能額代碼

如果采用工行模式和配置文件的方式進(jìn)行管理,則不需要修改客戶端程序,在配置文件中修改,來配置使用目標(biāo)類還是代理類,就很方便

1.2 AOP

安全,事務(wù),日志等功能貫穿到很多模塊中,所以是交叉業(yè)務(wù)
可以運(yùn)用代理的方法,來將交叉功能與實(shí)際功能區(qū)分開

1.3 動(dòng)態(tài)代理技術(shù)
要為系統(tǒng)中的各個(gè)接口的實(shí)現(xiàn)類添加代理功能,會(huì)需要太多的代理類,全部采用靜態(tài)代理的方式(就像AOP圖中的從method到func)就非常麻煩,因此需要?jiǎng)討B(tài)代理類
JVM可以在運(yùn)行期動(dòng)態(tài)生成出類的字節(jié)碼,這種類會(huì)用來做動(dòng)態(tài)代理功能 。JVM生成的動(dòng)態(tài)類必須實(shí)現(xiàn)至少一個(gè)接口,所以JVM生成的動(dòng)態(tài)類只能用作具有相同接口的目標(biāo)類的代理。但如果這個(gè)目標(biāo)類沒有接口呢,那JVM就不能生成這個(gè)類的動(dòng)態(tài)類了。
這就需要CGLIB庫可以動(dòng)態(tài)生成一個(gè)類的子類,一個(gè)類的子類也可以用作該類的代理,所以要為一個(gè)沒實(shí)現(xiàn)接口的目標(biāo)類生成動(dòng)態(tài)代理類,則需要CGLIB庫
代理類的各個(gè)方法除了要調(diào)用目標(biāo)的相應(yīng)方法和對外返回目標(biāo)方法返回結(jié)果外,還可以在如下四個(gè)位置添加各種功能:

調(diào)用目標(biāo)方法前

調(diào)用目標(biāo)方法后

調(diào)用目標(biāo)方法前后

在處理目標(biāo)方法異常的catch塊中

2.JVM生成動(dòng)態(tài)類

2.1 首先來看看動(dòng)態(tài)類的名字,構(gòu)造方法和其他方法

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;

public class Test {
    public static void main(String[] args) throws Exception {
        Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);// 生成的動(dòng)態(tài)類要為其指定類加載器與接口
        System.out.println(clazzProxy1.getName());
        
        Constructor[] constructors = clazzProxy1.getConstructors();        
        System.out.println("--------------------begin constructors list");
        for (Constructor constructor : constructors) {
            String name = constructor.getName();
            StringBuilder sBuilder=new StringBuilder(name);
            sBuilder.append("(");
            Class[] clazzParams=constructor.getParameterTypes();
            for (Class clazzParam : clazzParams) {
                sBuilder.append(clazzParam.getName()).append(",");
            }
            sBuilder.append(")");
            System.out.println(sBuilder);
        }
        
        
        Method[] methods = clazzProxy1.getMethods();
        System.out.println("---------------------begin methods list");
        for (Method method : methods) {
            String name = method.getName();
            StringBuilder sBuilder=new StringBuilder(name);
            sBuilder.append("(");
            Class[] clazzParams=method.getParameterTypes();
            for (Class clazzParam : clazzParams) {
                sBuilder.append(clazzParam.getName()).append(",");
            }
            sBuilder.append(")");
            System.out.println(sBuilder);
        }
    }
}

2.2 再來生成一個(gè)這個(gè)類的實(shí)例對象,三種方法

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;

public class Test {
    public static void main(String[] args) throws Exception {
        Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
        // 生成的動(dòng)態(tài)類要為其指定類加載器與接口,一般使用接口所用的加載器
        System.out.println(clazzProxy1.getName());
        
        Constructor[] constructors = clazzProxy1.getConstructors();        
        System.out.println("--------------------begin constructors list");
        for (Constructor constructor : constructors) {
            String name = constructor.getName();
            StringBuilder sBuilder=new StringBuilder(name);
            sBuilder.append("(");
            Class[] clazzParams=constructor.getParameterTypes();
            for (Class clazzParam : clazzParams) {
                sBuilder.append(clazzParam.getName()).append(",");
            }
            sBuilder.append(")");
            System.out.println(sBuilder);
        }
        
        
        Method[] methods = clazzProxy1.getMethods();
        System.out.println("---------------------begin methods list");
        for (Method method : methods) {
            String name = method.getName();
            StringBuilder sBuilder=new StringBuilder(name);
            sBuilder.append("(");
            Class[] clazzParams=method.getParameterTypes();
            for (Class clazzParam : clazzParams) {
                sBuilder.append(clazzParam.getName()).append(",");
            }
            sBuilder.append(")");
            System.out.println(sBuilder);
        }
        
        
        System.out.println("---------------------begin create instance");
        Constructor constructor=clazzProxy1.getConstructor(InvocationHandler.class);
        class MyInvocationHandler1 implements InvocationHandler{
            @Override
            public Object invoke(Object paramObject, Method paramMethod, Object[] paramArrayOfObject) throws Throwable {
                // TODO Auto-generated method stub
                return null;
            }
            
        }
        Collection proxy1=(Collection)constructor.newInstance(new MyInvocationHandler1());
        //創(chuàng)建的就是collection的子類
        System.out.println(proxy1);
        System.out.println(proxy1.toString());//說明proxy1并不是個(gè)空指針
        
        
        Collection proxy2=(Collection)constructor.newInstance(new InvocationHandler(){
            @Override
            public Object invoke(Object paramObject, Method paramMethod, Object[] paramArrayOfObject) throws Throwable {
                return null;
            }
        });
        
        Collection proxy3=(Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),
                new Class[]{
                    Collection.class    
                },
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object paramObject, Method paramMethod, Object[] paramArrayOfObject) throws Throwable {
                        
                        return null;
                    }
                });
    }
}

2.3 來看看InvocationHandler有什么用

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;

public class Test {
    public static void main(String[] args) throws Exception {
        Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
        // 生成的動(dòng)態(tài)類要為其指定類加載器與接口,一般使用接口所用的加載器
        System.out.println(clazzProxy1.getName());
        
        Constructor[] constructors = clazzProxy1.getConstructors();        
        System.out.println("--------------------begin constructors list");
        for (Constructor constructor : constructors) {
            String name = constructor.getName();
            StringBuilder sBuilder=new StringBuilder(name);
            sBuilder.append("(");
            Class[] clazzParams=constructor.getParameterTypes();
            for (Class clazzParam : clazzParams) {
                sBuilder.append(clazzParam.getName()).append(",");
            }
            sBuilder.append(")");
            System.out.println(sBuilder);
        }
        
        
        Method[] methods = clazzProxy1.getMethods();
        System.out.println("---------------------begin methods list");
        for (Method method : methods) {
            String name = method.getName();
            StringBuilder sBuilder=new StringBuilder(name);
            sBuilder.append("(");
            Class[] clazzParams=method.getParameterTypes();
            for (Class clazzParam : clazzParams) {
                sBuilder.append(clazzParam.getName()).append(",");
            }
            sBuilder.append(")");
            System.out.println(sBuilder);
        }
        
        
        System.out.println("---------------------begin create instance");
        Constructor constructor=clazzProxy1.getConstructor(InvocationHandler.class);
        class MyInvocationHandler1 implements InvocationHandler{
            @Override
            public Object invoke(Object paramObject, Method paramMethod, Object[] paramArrayOfObject) throws Throwable {
                // TODO Auto-generated method stub
                return null;
            }
            
        }
        Collection proxy1=(Collection)constructor.newInstance(new MyInvocationHandler1());
        //創(chuàng)建的就是collection的子類
        System.out.println(proxy1);
        System.out.println(proxy1.toString());//說明proxy1并不是個(gè)空指針
        
        
        Collection proxy2=(Collection)constructor.newInstance(new InvocationHandler(){
            @Override
            public Object invoke(Object paramObject, Method paramMethod, Object[] paramArrayOfObject) throws Throwable {
                return null;
            }
        });
        
        Collection proxy3=(Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),
                new Class[]{
                    Collection.class    
                },
                new InvocationHandler() {
                    ArrayList target=new ArrayList();
                    @Override
                    public Object invoke(Object paramObject, Method paramMethod, Object[] paramArrayOfObject) throws Throwable {
                        long beginTime=System.currentTimeMillis();
                        Object reVal=paramMethod.invoke(target, paramArrayOfObject);
                        long endTime=System.currentTimeMillis();
                        System.out.println(paramMethod.getName()+" running time of "+(endTime-beginTime));
                        return reVal;
                    }
                });
        proxy3.add("zzz");
        proxy3.add("ffffdd");
        proxy3.add("yyyy");
        /*
         * 在調(diào)用這個(gè)方法的時(shí)候,他都會(huì)找InvocationHandler的invoke方法
         */
        System.out.println(proxy3.size());
    }
}

實(shí)現(xiàn)原理解釋
構(gòu)造方法中接受了一個(gè)InvocationHandler對象,在新建動(dòng)態(tài)類實(shí)例對象之后,該對象調(diào)用一個(gè)方法的時(shí)候,比如上面調(diào)用了add方法,這個(gè)對象會(huì)實(shí)際是調(diào)用了proxy3的invoke方法,大概就像下面這樣

boolean add(Object paramE){
        return handler.invoke(this,this.getClass().getMethod("add", paramE.getClass()),paramE)
    }

注意,oject方法中只將hashcode,tostring,equal下發(fā)使用
在實(shí)際情況中,應(yīng)該將需要被處理(或者說添加功能)的對象與要添加的功能與動(dòng)態(tài)代理類分開,這樣在應(yīng)用的時(shí)候,只需要傳入對象與功能,就可以實(shí)現(xiàn)動(dòng)態(tài)代理,而不需要為每個(gè)要添加的功能多帶帶寫一個(gè)動(dòng)態(tài)代理類,把上面的例子改一下,結(jié)果如下:

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;

public class Test {
    public static void main(String[] args) throws Exception {
        Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
        // 生成的動(dòng)態(tài)類要為其指定類加載器與接口,一般使用接口所用的加載器
        System.out.println(clazzProxy1.getName());
        
        Constructor[] constructors = clazzProxy1.getConstructors();        
        System.out.println("--------------------begin constructors list");
        for (Constructor constructor : constructors) {
            String name = constructor.getName();
            StringBuilder sBuilder=new StringBuilder(name);
            sBuilder.append("(");
            Class[] clazzParams=constructor.getParameterTypes();
            for (Class clazzParam : clazzParams) {
                sBuilder.append(clazzParam.getName()).append(",");
            }
            sBuilder.append(")");
            System.out.println(sBuilder);
        }
        
        
        Method[] methods = clazzProxy1.getMethods();
        System.out.println("---------------------begin methods list");
        for (Method method : methods) {
            String name = method.getName();
            StringBuilder sBuilder=new StringBuilder(name);
            sBuilder.append("(");
            Class[] clazzParams=method.getParameterTypes();
            for (Class clazzParam : clazzParams) {
                sBuilder.append(clazzParam.getName()).append(",");
            }
            sBuilder.append(")");
            System.out.println(sBuilder);
        }
        
        
        System.out.println("---------------------begin create instance");
        Constructor constructor=clazzProxy1.getConstructor(InvocationHandler.class);
        class MyInvocationHandler1 implements InvocationHandler{
            @Override
            public Object invoke(Object paramObject, Method paramMethod, Object[] paramArrayOfObject) throws Throwable {
                // TODO Auto-generated method stub
                return null;
            }
            
        }
        Collection proxy1=(Collection)constructor.newInstance(new MyInvocationHandler1());
        //創(chuàng)建的就是collection的子類
        System.out.println(proxy1);
        System.out.println(proxy1.toString());//說明proxy1并不是個(gè)空指針
        
        
        Collection proxy2=(Collection)constructor.newInstance(new InvocationHandler(){
            @Override
            public Object invoke(Object paramObject, Method paramMethod, Object[] paramArrayOfObject) throws Throwable {
                return null;
            }
        });
        ArrayList target=new ArrayList();
        Collection proxy3=(Collection)getProxy(target,new MyAdvice());
        proxy3.add("zzz");
        proxy3.add("ffffdd");
        proxy3.add("yyyy");
        /*
         * 在調(diào)用這個(gè)方法的時(shí)候,他都會(huì)找InvocationHandler的invoke方法
         */
        System.out.println(proxy3.size());
        System.out.println(proxy3);
    }

    private static Object getProxy(Object target,Advice advisor) {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object paramObject, Method paramMethod, Object[] paramArrayOfObject) throws Throwable {
                        advisor.beforeMethod(paramMethod);
                        Object reVal=paramMethod.invoke(target, paramArrayOfObject);
                        advisor.afterMethod(paramMethod);
                        return reVal;
                    }
                });
    }
}

interface Advice{
    void beforeMethod(Method method);
    void afterMethod(Method method);
}

class MyAdvice implements Advice{
    long beginTime=0;
    @Override
    public void afterMethod(Method method) {
        System.out.println("結(jié)束");
        long endTime=System.currentTimeMillis();
        System.out.println(method.getName()+" running time of "+(endTime-beginTime));
    }

    @Override
    public void beforeMethod(Method method) {
        System.out.println("開始");
        beginTime=System.currentTimeMillis();
    }
    
}

這樣,如果我想給A對象添加一個(gè)α功能,那就傳個(gè)A和實(shí)現(xiàn)了α功能的advisor類就可以了,改明兒要是想把α功能換成β功能,直接將參數(shù)換成一個(gè)新的實(shí)現(xiàn)了β功能的advisor類就可以了,不用再去重新寫一個(gè)InvocationHandler。代碼分離,易于維護(hù)。

2.4 實(shí)現(xiàn)類似spring的可配置AOP框架

需求:如果傳入的是普通類,則返回普通類實(shí)例對象,如果傳入的是需要代理的類,則返回代理類的動(dòng)態(tài)代理對象,通過修改配置文件來進(jìn)行切換

package zheteng;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class BeanFactory {
    Properties props=new Properties();
    public BeanFactory(InputStream ips) {
        try {
            props.load(ips);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public Object getBean(String name){
        String className=props.getProperty(name);
        Object bean=null;
        try {
            Class clazz=Class.forName(className);
            bean=clazz.newInstance();
            if(bean instanceof ProxyFactoryBean){
                ProxyFactoryBean proxyFactoryBean=(ProxyFactoryBean)bean;
                Advice advisor=(Advice) Class.forName(props.getProperty(name+".advice")).newInstance();
                Object target=Class.forName(props.getProperty(name+".target")).newInstance();
                proxyFactoryBean.setAdvisor(advisor);
                proxyFactoryBean.setTarget(target);
                Object proxy=proxyFactoryBean.getProxy();
                return proxy;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return bean;
    }
}
package zheteng;

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

public class ProxyFactoryBean {

    private Advice advisor;
    private Object target;
    public Advice getAdvisor() {
        return advisor;
    }
    public void setAdvisor(Advice advisor) {
        this.advisor = advisor;
    }
    public Object getTarget() {
        return target;
    }
    public void setTarget(Object target) {
        this.target = target;
    }
    public Object getProxy() {
        // TODO Auto-generated method stub
        Object proxy3=Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
            new InvocationHandler() {
                @Override
                public Object invoke(Object paramObject, Method paramMethod, Object[] paramArrayOfObject) throws Throwable {
                    advisor.beforeMethod(paramMethod);
                    Object reVal=paramMethod.invoke(target, paramArrayOfObject);
                    advisor.afterMethod(paramMethod);
                    return reVal;
                }
            });
        return proxy3;
    }

}

interface Advice{
    void beforeMethod(Method method);
    void afterMethod(Method method);
}
class MyAdvice implements Advice{
    long beginTime=0;
    @Override
    public void afterMethod(Method method) {
        System.out.println("結(jié)束");
        long endTime=System.currentTimeMillis();
        System.out.println(method.getName()+" running time of "+(endTime-beginTime));
    }

    @Override
    public void beforeMethod(Method method) {
        System.out.println("開始");
        beginTime=System.currentTimeMillis();
    }
    
}
package zheteng;

import java.io.InputStream;

public class AopFrameworkTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");
        System.out.println(ips);
        Object bean = new BeanFactory(ips).getBean("xxx");
        System.out.println(bean.getClass());
    }

}
#xxx=java.util.ArrayList
xxx=zheteng.ProxyFactoryBean
xxx.advice=zheteng.MyAdvice
xxx.target=java.util.ArrayList

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/67502.html

相關(guān)文章

  • Java程序員的成長之路

    摘要:雖然題目是寫的程序員,但對其他語言的開發(fā)來說也會(huì)有借鑒作用。一定要記住,作為一個(gè)程序猿,平日里所接觸的技術(shù)可能會(huì)很多,但是想要讓一門技術(shù)成為你的優(yōu)勢,那么一定是你對這門技術(shù)的了解強(qiáng)過絕大多數(shù)人才行。 閱讀本文大概需要 8.2 分鐘。 tips:雖然題目是寫的Java程序員,但對其他語言的開發(fā)來說也會(huì)有借鑒作用。 本篇介紹的是大體思路,以及每個(gè)節(jié)點(diǎn)所需要學(xué)習(xí)的書籍內(nèi)容,如果大家對詳細(xì)的技...

    stormjun 評論0 收藏0
  • 樂字節(jié)Java之file、IO流基礎(chǔ)知識和操作步驟

    摘要:流分類由此可見,流很龐大從不同角度進(jìn)行分類數(shù)據(jù)分類按處理數(shù)據(jù)單位分為字節(jié)流和字符流。處理數(shù)據(jù)是音頻視頻文本等一切為字節(jié)流,僅能處理文本的為字符流。功能分類節(jié)點(diǎn)流和處理流。從向一個(gè)特定的設(shè)備磁盤網(wǎng)絡(luò)等讀寫數(shù)據(jù)的流稱為節(jié)點(diǎn)流,也常被稱為低級流。 嗨嘍,小樂又來了,今天要給大家送上的技術(shù)文章是Java重點(diǎn)知識-IO流。 先來看看IO流的思維導(dǎo)圖吧。showImg(https://segmen...

    pkhope 評論0 收藏0
  • NIO網(wǎng)絡(luò)相關(guān)基礎(chǔ)知識

    摘要:操作系統(tǒng)是能夠獲取到事件操作完成的事件,基于回調(diào)函數(shù)機(jī)制和操作系統(tǒng)的操作控制實(shí)現(xiàn)事件檢測機(jī)制。 前面的文章NIO基礎(chǔ)知識介紹了Java NIO的一些基本的類及功能說明,Java NIO是用來替換java 傳統(tǒng)IO的,NIO的一些新的特性在網(wǎng)絡(luò)交互方面會(huì)更加的明顯。 Java 傳統(tǒng)IO的弊端 ????基于JVM來實(shí)現(xiàn)每個(gè)通道的輪詢檢查通道狀態(tài)的方法是可行的,但仍然是有問題的,檢查每個(gè)通道...

    1fe1se 評論0 收藏0
  • 阿里p8架構(gòu)師談,對于Java程序猿學(xué)習(xí)當(dāng)中各個(gè)階段的建議。

    摘要:第三部分對于參加工作年到年的同學(xué)。我當(dāng)時(shí)看的是大話設(shè)計(jì)模式這本書,并且寫了完整版的設(shè)計(jì)模式博客。這一年,你必須對于設(shè)計(jì)模式了如指掌,大話設(shè)計(jì)模式可以作為你的開端。與此同時(shí),這個(gè)階段你要做的事情還遠(yuǎn)不止如此。 這一部分其實(shí)也算是今天的重點(diǎn),這一部分用來回答很多群里的朋友所問過的問題,那就是大佬你是如何學(xué)習(xí)Java的,能不能給點(diǎn)建議? 今天我是打算來點(diǎn)干貨,因此咱們就不說一些學(xué)習(xí)方法和技巧...

    sevi_stuo 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<