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.

  • 相关阅读:
    Solution -「ARC 101D」「AT4353」Robots and Exits
    Solution -「多校联训」轮回
    Solution -「多校联训」种蘑菇
    Solution -「多校联训」染色
    luoguP4389 完全背包计数
    Js 之notification浏览器桌面通知
    Linux 之shell脚本调用另一个shell脚本
    Linux 之开机自启动脚本
    Js 之简单ajax封装
    PHP 之phpsocket.io客户端主动推送给服务器
  • 原文地址:https://www.cnblogs.com/luowei010101/p/2617426.html
Copyright © 2011-2022 走看看