Java 反射、枚举——Java学习笔记28(补)

在这里插入图片描述

〇、写在前面 碎碎念

  终于要把基础的课程给结束了,其实早该结束了。给自己加个油。It will get better.
  2019.3.20
  为了丁丁女朋友加油吧!
  2019.3.21

一、反射的概述

1. 获取Class文件对象的三种方式

	Class<?> clazz = Class.forName("全类名");		//用于读取配置文件
	Class<?> clazz = Person.class;					//当作静态方法的同步锁对象
	Class<?> clazz = p.getClass();					//判断是否是同一个字节码对象(HashCode()方法中使用到)

2.用Class对象来创建实例

	Class clazz = Class.forName(lassName);
	Person p = (Person)clazz.newInstance();

3.通过反射获取xxx

(1) 构造方法getConstructor[s] (Class … [parameterTypes);

	Constructor<?> con = clazz.getConstructor(String.class,int.class);
Constructor 中的方法
	public T newInstance(Object args) throws manyException;		//通过构造方法来获取创建实例对象

(2) 成员变量getField[s] (“name”);

	Field[] f = clazz.getFields();

(3) 成员方法getMethod[s] (String name, Class … parameterTypes)

	Method me = clazz.getMethod("say",String.class);
Method 中的方法
	public void invoke(Object o,Object ...parameterTypes);		//执行有参方法
	public void invoke(Object o);								//执行无参方法

三、动态代理

概述

  (用自己的话来说)通过反射的方法来调用了class对象,给class对象所映射的类的每一个方法都加上一些额外的功能。无论是Animal接口的子类还是Person接口的子类,通过动态代理的方法都能在每个方法中添加额外的代理功能代码.
  使用到的类和接口:Proxy类和InvocationHandler接口

具体步骤

  1. 已有Person接口和实现了Person接口的子类PersonImp类
  2. 创建一个MyInvocationHandler类实现了InvocationHandler接口;
  3. 在该类中创建一个Object target对象,并私有;
  4. 创建有参构造传入一个Object target对象;
  5. 在该类中重写了invoke方法,形参是Object proxy,Method method, Object[] args.我们只需关注methodargs(类中调用方法的形参列表);
  6. 在invoke方法中调用method.invoke(target,args);在加上需要添加的代理功能代码;
  7. 在测试类中新建一个Person p = new PersonImp();
  8. 用Person接口来接受Proxy类中的静态方法(Person)newProxyInstance(ClassLoader c,Interface i,InvocationHandler h)的返回值
  9. 调用原来的方法会发现加上了代理的功能方法

代码实现

public class MyInvocationHandler implements InvocationHandler {
	private Object target;
	public MyInvocationHandler(Object target) {
		this.target = target;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("xxxxx代码");
		method.invoke(target, args);
		System.out.println("yyyyyy代码");
		return null;
	}
}
public static void main(String[] args) {
	Person p = new PersonImps();
		
	p.drink();
	p.eat();
	p.sleep();
	System.out.println("-----------");
	Person p1 = (Person) Proxy.newProxyInstance(p.getClass().getClassLoader(), 
			p.getClass().getInterfaces(), new MyInvocationHandler(p));
	p1.drink();
	p1.eat();
	p1.sleep();
}

Result:
在这里插入图片描述

四、设计模式之 模板设计模式(Template)

概述

  • 模版设计模式概述
    • 模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现
  • 优点和缺点
    • 优点
      • 使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求
    • 缺点
      • 如果算法骨架有修改的话,则需要修改抽象类
        在这里插入图片描述

五、枚举(enum)

1. 概述

  枚举相当于单例设计模式的衍生,相当于多例设计模式。
  1/自定义的实现枚举的方法
  使用单例设计模式的第三种创建方法,私有构造方法,将设置的实例用final修饰,在类中指定生成实例的个数。
  2/使用enum关键字实现枚举类

2. 自定义实现枚举的方法

public abstract class Week2 {
	private String name;
	private Week2(String name) {		//私有构造,不让其他类创建本类对象
		this.name = name;
	}				
	
	
	public String getName() {			//对外提供公共的获取方法
		return name;
	}

	public abstract void  show();		//设置抽象方法

	//使用匿名内部类的方式来创建抽象类的子类对象
	public static final Week2 MON = new Week2("周一") {
		@Override
		public void show() {
			System.out.println("周一惹");
		}
	};
	public static final Week2 TUE = new Week2("周二") {
		@Override
		public void show() {
			System.out.println("周二惹");
		}
	};
	public static final Week2 WED = new Week2("周三") {
		@Override
		public void show() {
			System.out.println("周三惹");
		}
	};
}

3. enum来实现枚举

public enum Week2 {
	Mon("周一"){
		@Override
		public void show() {
			System.out.println("你好周一");
		}
	},The("周二"){
		@Override
		public void show() {
			System.out.println("你好周二");
		}
	},Wed("周三"){
		@Override
		public void show() {
			System.out.println("你好周三");
		}
	};
	String name;
	private Week2(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	
	public abstract void show();
}

4. enum的注意事项

  • 定义枚举类要用关键字enum
  • 所有枚举类都是Enum的子类
  • 枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其他的东西,这个分号就不能省略。建议不要省略
  • 枚举类可以有构造器,但必须是private的,它默认的也是private的。
  • 枚举类也可以有抽象方法,但是枚举项必须重写该方法
  • 枚举在switch语句中的使用

(1) 枚举在switch语句中的使用

Week2 mon = Week2.Mon;
switch (mon) {
case Mon:
	System.out.println("周一好");
	break;
case Tue:
	System.out.println("周二好");
	break;
case Wed:
	System.out.println("周三好");
	break;
}

5.枚举Method

	int ordinary();			//返回枚举常量的序数
	int compareTo();		//比较编号...,相当于做减法
	String name();			//获取实例名称
	String toString();		//未重写时=name()方法
	T <T> values();			//返回枚举项数组
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值