您的位置:首页 > 编程语言 > Java开发

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

2012-07-31 21:37 771 查看
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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐