java笔记1(策略、代理模式、枚举、反射、注解)

java笔记1(策略、代理模式、枚举、反射、注解)

一个简单策略模式示例的实现

1.策略模式的组成

2.策略模式的实现

3.策略械的编写步骤

 

注:java中的Collections 就是策略模式的一个实现, 其中的很多方法通过传入不同的比较器,实现不同形式的比较。

4.定义一个实体类

package com.vvvv.strategy;

public class Person{

    private int id;

    private String name;

    private int age;

   

    …………get/set方法…………

}

5.定义策略接口

package com.vvvv.strategy;

import java.util.List;

public interface SortInterface{

    public void sort(List<Person> list);

}

6.具体的策略类

1.根据名字升序

package com.vvvv.strategy;

import java.util.Collections;

import java.util.Comparator;

import java.util.List;

public class UpNameSort implements SortInterface, Comparator<Person>{

    public void sort(List<Person> list) {

        Collections.sort(list, this);

    }

   

    public int compare(Person o1, Person o2){

        int result = o1.getName().compareTo(o2.getName());

        if(0 == result) {

            return o1.getId() - o2.getId();

        }

        return result;

    }

}

2.根据名字降序

package com.vvvv.strategy;

import java.util.Collections;

import java.util.Comparator;

import java.util.List;

public class DownNameSort implements SortInterface, Comparator<Person>{

    public void sort(List<Person> list) {

        Collections.sort(list, this);

    }

   

    public int compare(Person o1, Person o2) {

        int result = o2.getName().compareTo(o1.getName());

        if(0 == result) {

            return o1.getId() - o2.getId();

        }

        return result;

    }

}

7.应用的环境类

package com.vvvv.strategy;

import java.util.List;

public class Environment{

    private SortInterface sortInterface;

    public Environment(SortInterface sortInterface){

        this.sortInterface = sortInterface;

    }

   

    public Environment()

       

    }

   

    public void setSortInterface(SortInterface sortInterface){

        this.sortInterface = sortInterface;

    }

   

    public void sort(List<Person> list){

        this.sortInterface.sort(list);

    }

}

8.客户端的调用

package com.vvvv.strategy;

import java.util.ArrayList;

import java.util.List;

public class Client{

    public static void main(String[] args) {

        Person p1 = new Person();

        p1.setName("Tom");

        p1.setId(1);

        p1.setAge(20);

 

        Person p2 = new Person();

        p2.setName("Tonny");

        p2.setId(2);

        p2.setAge(50);

 

        Person p3 = new Person();

        p3.setName("Tom");

        p3.setId(5);

        p3.setAge(30);

 

        Person p4 = new Person();

        p4.setName("ABC");

        p4.setId(8);

        p4.setAge(10);

 

        Person p5 = new Person();

        p5.setName("Xyz");

        p5.setId(9);

        p5.setAge(15);

 

        List<Person> list = new ArrayList<Person>();

        list.add(p1);

        list.add(p2);

        list.add(p3);

        list.add(p4);

        list.add(p5);

 

        Environment env = new Environment();

        UpNameSort uns = new UpNameSort();

        env.setSortInterface(uns);

        env.sort(list);

        for (int i = 0; i < list.size(); i++){

            Person p = list.get(i);

            System.out.println("id: " + p.getId() + ", name: " + p.getName()

                    + ", age:" + p.getAge());

        }

 

        System.out.println("--------------");

        DownNameSort dns = new DownNameSort();

        env.setSortInterface(dns);

        env.sort(list);

        for (int i = 0; i < list.size(); i++){

            Person p = list.get(i);

            System.out.println("id: " + p.getId() + ", name: " + p.getName()

                    + ", age:" + p.getAge());

        }

    }

}

枚举类型

1.枚举的每一个成员就是它一个实例,编译时确定

package com.vvvv.jdk5;

public enum Coin{

    penny("hello"), nickel("world"), dime("welcome"), quarter("hello world");

    private String value;

   

    public String getValue(){

        return value;

    }

   

    Coin(String value) {

        this.value = value;

    }

   

    public static void main(String[] args) {

        Coin coin = Coin.quarter;

        System.out.println(coin.getValue());

    }

}

2.构造EnumMap

package com.vvvv.jdk5;

import java.util.EnumMap;

import java.util.Map;

public class EnumMapDemo{

    public static void main(String[] args) {

        Map<Action, String> map = new EnumMap<Action, String>(Action.class);

        map.put(Action.TURN_RIGHT, "向右转");

        map.put(Action.SHOOT, "射击");

        map.put(Action.TURN_LEFT, "向左转");

        for (Action action : Action.values()){

            System.out.println(map.get(action));

        }

    }

}

 

enum Action{

TURN_LEFT, TURN_RIGHT, SHO

}

3.构造EnumSet

package com.vvvv.jdk5;

import java.util.EnumSet;

import java.util.Iterator;

public class EnumSetDemo2{

    public static void main(String[] args) {

        EnumSet<FontConstant> enumSet = EnumSet.noneOf(FontConstant.class);

        enumSet.add(FontConstant.Bold);

        enumSet.add(FontConstant.Italilc);

        showEnumSet(enumSet);

    }

   

    public static void showEnumSet(EnumSet<FontConstant> enumSet) {

        for(Iterator<FontConstant> iter = enumSet.iterator(); iter.hasNext();){

            System.out.println(iter.next());

        }

    }

}

4.构造EnumList

package com.vvvv.jdk5;

import java.util.EnumSet;

import java.util.Iterator;

public class EnumSetDemo2{

    public static void main(String[] args) {

        EnumSet<FontConstant> enumSet = EnumSet.noneOf(FontConstant.class);

        enumSet.add(FontConstant.Bold);

        enumSet.add(FontConstant.Italilc);

        showEnumSet(enumSet);

    }

   

    public static void showEnumSet(EnumSet<FontConstant> enumSet) {

        for(Iterator<FontConstant> iter = enumSet.iterator(); iter.hasNext();){

            System.out.println(iter.next());

        }

    }

}

反射

1.使用forName

package com.vvvv.reflect;

import java.lang.reflect.Method;

public class DumpMethods{

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

        Class<?> classType = Class.forName(args[0]);

        Method[] methods = classType.getDeclaredMethods();

        for(Method method : methods) {

            System.out.println(method);

        }

    }

}

2.使用.class语法

package com.vvvv.reflect;

import java.lang.reflect.Method;

public class InvokeTester{

    public int add(int param1, int param2) {

        return param1 + param2;

    }

    public String echo(String message) {

        return "hello: " + message;

    }

 

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

        // InvokeTester test = new InvokeTester();

        // System.out.println(test.add(1, 2));

        // System.out.println(test.echo("tom"));

        Class<?> classType = InvokeTester.class;

        Object invokeTester = classType.newInstance();

        // System.out.println(invokeTester instanceof InvokeTester);

        Method addMethod = classType.getMethod("add",new Class[]{int.class,

                int.class});

        Object result = addMethod.invoke(invokeTester,new Object[]{1,2});

        System.out.println((Integer)result);

        System.out.println("---------------------");

        Method echoMethod = classType.getMethod("echo", new Class[]{String.class});

        Object result2 = echoMethod.invoke(invokeTester, new Object[]{"tom"});

        System.out.println((String)result2);

    }

}

3.利用反射实现对象的拷贝

package com.vvvv.reflect;

 

import java.lang.reflect.Field;

import java.lang.reflect.Method;

public class ReflectTester{

    // 该方法实现对Customer对象的拷贝操作

    public Object copy(Object object) throws Exception{

        Class<?> classType = object.getClass();

        Object objectCopy = classType.getConstructor(new Class[] {}).newInstance(new Object[] {});

        // 获得对象的所有成员变量

        Field[] fields = classType.getDeclaredFields();

        for (Field field : fields) {

            String name = field.getName();

            String firstLetter = name.substring(0, 1).toUpperCase();// 将属性的首字母转换为大写

            String getMethodName = "get" + firstLetter + name.substring(1);

            String setMethodName = "set" + firstLetter + name.substring(1);

            Method getMethod = classType.getMethod(getMethodName, new Class[] {});

            Method setMethod = classType.getMethod(setMethodName, new Class[] { field.getType() });

            Object value = getMethod.invoke(object, new Object[] {});

            setMethod.invoke(objectCopy, new Object[] { value });

        }

 

        // 以上两行代码等价于下面一行

        // Object obj2 = classType.newInstance();

        // System.out.println(obj);

        return objectCopy;

    }

 

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

        Customer customer = new Customer("Tom", 20);

        customer.setId(1L);

        ReflectTester test = new ReflectTester();

        Customer customer2 = (Customer) test.copy(customer);

        System.out.println(customer2.getId() + "," + customer2.getName() + ","

                + customer2.getAge());

    }

}

 

class Customer{

    private Long id;

    private String name;

    private int age;

    public Customer(){

}

    public Customer(String name, int age) {

        this.name = name;

        this.age = age;

    }

    …………set 、get方法…………

}

4.创建数组

示例1:

package com.vvvv.reflect;

import java.lang.reflect.Array;

public class ArrayTester1{

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

        Class<?> classType = Class.forName("java.lang.String");

        //创建一个数组长度为10的数组

        Object array = Array.newInstance(classType, 10);

       //设置数组的第5个元素

        Array.set(array, 5, "hello");

       //取出第5个元素

        String str = (String)Array.get(array, 5);

        System.out.println(str);

    }

}

示例2:

package com.vvvv.reflect;

import java.lang.reflect.Array;

public class ArrayTester2{

    public static void main(String[] args){

        int[] dims = new int[] { 5, 10, 15 };

        //创建一个长宽高分别为5、10、15的三维数组

        Object array = Array.newInstance(Integer.TYPE, dims);

       

        System.out.println(array instanceof int[][][]);

        //获得array的第1维下标为3的component

        Object arrayObj = Array.get(array, 3);

       

        //获得arrayObj的第1维下标为5的component,并赋给arrayObj

        arrayObj = Array.get(arrayObj, 5);

       

        //设置arrayObj第10个元素的值

        Array.setInt(arrayObj, 10, 37);

 

        int[][][] arrayCast = (int[][][]) array;

        System.out.println(arrayCast[3][5][10]);

 

        // System.out.println(Integer.TYPE);

        // System.out.println(Integer.class);

    }

}

代理模式

1.静态代理

示例1

抽象角色

package com.vvvv.proxy;

public abstract class Subject{

    public abstract void request();

}

真实角色

package com.vvvv.proxy;

public class RealSubject extends Subject{

    public void request(){

        System.out.println("From real subject.");

    }

}

代理角色

package com.vvvv.proxy;

public class ProxySubject extends Subject{

    private RealSubject realSubject; //代理角色内部引用了真实角色

    public void request(){

        this.preRequest(); //在真实角色操作之前所附加的操作

        if(null == realSubject){

            realSubject = new RealSubject();

        }

        realSubject.request(); //真实角色所完成的事情

        this.postRequest(); //在真实角色操作之后所附加的操作

    }

   

    private void preRequest(){

        System.out.println("pre request");

    }

   

    private void postRequest(){

        System.out.println("post request");

    }

}

客户端

package com.vvvv.proxy;

public class Client{

    public static void main(String[] args){

        Subject subject = new ProxySubject();

        subject.request();

    }

}

2.动态代理

创建动态代理的步骤:

1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法

2.创建被代理的类以及接口

3.通过Proxy的静态方法newProxyInstance(ClassLoader loader, Class[] interfaces,InvocationHandler  h) 创建一个代理

4.通过代理调用方法

抽象角色与真实角色同上静态代理

动态代理句柄,可以动态的接收真实现角色、并调用真实角色的方法

package com.vvvv.dynamicproxy;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

/**

该代理类的内部属性是Object类型,实际使用的时候通过该类的构造方法传递进来一个对象

 * 此外,该类还实现了invoke方法,该方法中的method.invoke其实就是调用被代理对象的将要

 * 执行的方法,方法参数是sub,表示该方法从属于sub,通过动态代理类,我们可以在执行真实对象的方法前后

 * 加入自己的一些额外方法。

 */

 

public class DynamicSubject implements InvocationHandler{

    private Object sub;

    public DynamicSubject(Object obj){

        this.sub = obj;

    }

   

    public Object invoke(Object proxy, Method method, Object[] args)

            throws Throwable{

        System.out.println("before calling: " + method);

        method.invoke(sub, args);

        System.out.println(args == null);

        System.out.println("after calling: " + method);

        return null;

    }

}

客户端

package com.vvvv.dynamicproxy;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Proxy;

public class Client{

    public static void main(String[] args){

        RealSubject realSubject = new RealSubject();

       //动态代理句柄类拿到真实对象的引用,并构造一个对象

        InvocationHandler handler = new DynamicSubject(realSubject);

        Class<?> classType = handler.getClass();

 

        //生成代理对象

        Subject subject = (Subject) Proxy.newProxyInstance(

classType.getClassLoader(),  //类加载器

realSubject.getClass().getInterfaces(),  //真实对象实现的接口

                handler);

        subject.request();

        System.out.println(subject.getClass());

    }

}

自定义一个对Vector的动态代理句柄

package com.vvvv.dynamicproxy;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.List;

import java.util.Vector;

 

public class VectorProxy implements InvocationHandler{

    //这里传入的真实对象将会是Vector的对象

    private Object realObj;

    public VectorProxy(Object obj){

        this.realObj = obj;

    }

 

    //构造代理对象

    public static Object factory(Object obj){

        Class<?> classType = obj.getClass();

        return Proxy.newProxyInstance(classType.getClassLoader(),

                classType.getInterfaces(), new VectorProxy(obj));

    }

   

    //通过代理角色执行方法调用

    public Object invoke(Object proxy, Method method, Object[] args)

            throws Throwable{

        System.out.println("before calling: " + method);

        if(null != args){

           //args是method的参数

            for(Object obj : args){

                System.out.println(obj);

            }

        }

        //调用代理角色的目标方法

        Object object = method.invoke(proxyObj, args);

        System.out.println("after calling: " + method);

        return object;

    }

   

    public static void main(String[] args){

        List v = (List)factory(new Vector());

        System.out.println(v.getClass().getName());

       

        //通过代理对象v间接调用vector的方法

        v.add("New");

        v.add("York");

        System.out.println(v);

        v.remove(0);

        System.out.println(v);

    }

}

注解

说明

1.自定义注解:当注解中的属性名为 value 时,在对其赋值时可以不指定属性的名称而直接写上属性值即可;除了value 以外的其他值都需要使用 name=value这种赋值方式,即明确指定给谁赋值。

2.当我们使用@interface 关键字定义一个注解时,该注解隐含地继承了java.lang.annotation.Annotation 接口;如果我们定义了一个接口,并且让该接口继承自 Annotation,那么我们所定义的接口依然还是接口而不是注解;Annotation 本身是接口而不是注解。可以与Enum 类比。

自定义注解

示例1

AnnotationTest

package com.vvvv.annotation;

public @interface AnnotationTest{

    String[] value1() default "hello";

    EnumTest value2();

}

 

enum EnumTest{

    Hello, World, Welcome;

}

AnnotationUsage

package com.vvvv.annotation;

 

@AnnotationTest(value2 = EnumTest.Welcome)

public class AnnotationUsage{

    @AnnotationTest(value1 = {"world", "ABCD"}, value2 = EnumTest.World)

    public void method(){

        System.out.println("usage of annotation");

    }

   

    public static void main(String[] args){

        AnnotationUsage usage = new AnnotationUsage();

        usage.method();

    }

}

@Retention及RetentionPolicy的使用

Retention可以指定注解的保留策略,包括Class,Runtime,Source三个范围域上。

示例2

MyAnnotation

package com.vvvv.annotation;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

 

@Retention(RetentionPolicy.CLASS)

public @interface MyAnnotation{

    String hello() default "vvvv";

    String world();

}

MyTest

package com.vvvv.annotation;

 

@MyAnnotation(hello = "beijing", world = "shanghai")

public class MyTest{

    @MyAnnotation(hello = "tianjin", world = "shangdi")

    @Deprecated

    @SuppressWarnings("unchecked")

    public void output(){

        System.out.println("output something!");

    }

}

利用反向射读取注解信息

示例3

AccessibleObject, Class, Constructor, Field, Method, Package都实现了AnnotatedElement接口. 定义Annotation时必须设定RetentionPolicy为RUNTIME,也就是可以在VM中读取Annotation信息。以下示例使用反射方式,读取出定义在类上的注解信息。

MyRefection

package com.vvvv.annotation;

 

import java.lang.annotation.Annotation;

import java.lang.reflect.Method;

 

public class MyReflection{

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

        MyTest myTest = new MyTest();

        Class<MyTest> c = MyTest.class;

        Method method = c.getMethod("output", new Class[]{});

       

        //判断这个注解上是否存在MyAnnotation的注解修饰

        if(method.isAnnotationPresent(MyAnnotation.class)){

            method.invoke(myTest, new Object[]{});

           

            //获得MyAnnotation注解,并取出MyAnnotation注解的值

            MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);

            String hello = myAnnotation.hello();

            String world = myAnnotation.world();

            System.out.println(hello + ", " + world);

        }

        //获得这个方法的所有注解

        Annotation[] annotations = method.getAnnotations();

        for(Annotation annotation : annotations){

           //输出的内容由注解的RetentionPolicy决定

            System.out.println(annotation.annotationType().getName());

        }

}

@Target限定注解的使用时机

       使用@Target定义注解的使用时机要指定java.lang.annotation.ElementType,是AccessibleObject,还是 Class, 或者Constructor, Field, Method, Package.

       @Retention要搭配一个RetentionPolicy枚举类型, 同样@Target要搭配一个ElmentType 枚举类型。

示例4

MyTarget

package com.vvvv.annotation;

 

import java.lang.annotation.ElementType;

import java.lang.annotation.Target;

 

@Target(ElementType.METHOD)

public @interface MyTarget{

    String value();

}

MyTargetTest

package com.vvvv.annotation;

 

public class MyTargetTest{

    @MyTarget("hello")

    public void doSomething(){

        System.out.println("hello world");

    }

}

1.使用java.lang.annotation.Documented修改注解,则可以将注解的信息加入到API文档中。

2.预设的父类别中的Annotation并不会继承到子类别中,但可以在定义Annotation型态时加上java.lang.annotation.Inherited型态的Annotation.

原文地址:https://www.cnblogs.com/luowei010101/p/2617426.html