zoukankan      html  css  js  c++  java
  • 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.

  • 相关阅读:
    mac os programming
    Rejecting Good Engineers?
    Do Undergrads in MIT Struggle to Obtain Good Grades?
    Go to industry?
    LaTex Tricks
    Convert jupyter notebooks to python files
    How to get gradients with respect to the inputs in pytorch
    Uninstall cuda 9.1 and install cuda 8.0
    How to edit codes on the server which runs jupyter notebook using your pc's bwroser
    Leetcode No.94 Binary Tree Inorder Traversal二叉树中序遍历(c++实现)
  • 原文地址:https://www.cnblogs.com/luowei010101/p/2617426.html
Copyright © 2011-2022 走看看