java 反射、设计模式、枚举、注解


在这里插入图片描述

  类的对象,基于某个类 new 出来的对象,也称为实例对象。
  类对象,类加载的产物,封装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法)。

  通过反射获取类对象。


// 通过类的对象,获取类对象
Student s = new Student();
Class c = s.getClass();

// 通过类名获取类对象
Class c = 类名.class;

// 通过静态方法获取类对象
Class c=Class.forName(“包名.类名”);

  通过类对象获取类信息。

// Person 类
public class Person implements Serializable {
	
	private String name;
	
	int age;

	public Person() {
		// TODO Auto-generated constructor stub
	}
	
	public String getName() {
		return name;
	}

	public void hello(String name,int age) {
		System.out.println(name+"--->"+age);
	}

}


public class Test {
	
	public static void main(String[] args) throws InstantiationException, IllegalAccessException {
		
		// 反射对象
		Class c1 = Person.class;
		
		// 全类名
		System.out.println(c1.getName());
		
		// 包名
		System.out.println(c1.getPackage());
		
		// 父类
		System.out.println(c1.getSuperclass());
		
		// 接口
		System.out.println(c1.getInterfaces());
		
		// 方法 包含父类的方法
		System.out.println(c1.getMethods());
		
		// 属性
		System.out.println(c1.getFields());
		
		// 构造器
		System.out.println(c1.getConstructors());
		
		// 实例化对象
		System.out.println(c1.newInstance());	
	}
}

  通过反射对类的私有属性赋值。


public class Test1 {
	
	public static void main(String[] args) throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
		
		Class c1 = Person.class;
		
		// 私有属性的 Field对象
		Field field = c1.getDeclaredField("name");
		
		Person obj = (Person)c1.newInstance();
		
		//给Field属性设置权限
		field.setAccessible(true);
		
		// 通过 Field 给 name 赋值
		field.set(obj, "张三");
		
		// 取值
		System.out.println(field.get(obj));
		
		// 验证跟类关联了
		System.out.println(obj.getName());
	}
}

  通过反射对象调用方法。


public class Test1 {

	public Test1() {
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
		
		Class t1 = Person.class;
		
		// 反射公有方法,返回 Method 对象
		Method m1 = t1.getMethod("hello", String.class, int.class);
		
		Object obj = t1.newInstance();
		
		//通过Method 对象 的 invoke 调用类的 hello 方法
		m1.invoke(obj, "张三", 18);

	}
}

  设计模式。一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。可以简单理解为特定问题的固定解决方法。
  工厂设计模式。开闭原则,对拓展开放、对修改关闭。

  工厂设计模式 和 反射结合,完成动态的对象创建。

//
public class Cat {

	public String name;
	
	public Cat() {
		// TODO Auto-generated constructor stub
	}

}

//
public class Dog {

	public String name;
	
	public Dog() {
		// TODO Auto-generated constructor stub
	}

}

// 工厂类的方法里,将反射对象传入返回实例化对象
public class Factory {

	public Factory() {
		// TODO Auto-generated constructor stub
	}
	
	public static Object newInstance(Class<?> cla) throws InstantiationException, IllegalAccessException {
		
		return cla.newInstance();
	}
}

public class Test1 {

	public static void main(String[] args) throws InstantiationException, IllegalAccessException {
		
		// 工厂模式 + 反射,一个方法可以实例化多个类
		Object o1 = Factory.newInstance(Dog.class);
		Dog dog = (Dog)o1;
		
		Object o2 = Factory.newInstance(Cat.class);
		Cat cat = (Cat)o2;
		
		dog.name = "小狗狗";
		cat.name = "小猫猫";
		
	}
}

  单例模式。只允许创建一个该类的对象。

  饿汉式。类加载时创建,天生线程安全。


public class Single1 {

	// 私有 静态当前类属性
	private static final Single1 single = new Single1();
	
	// 私有构造方法
	private Single1() {
		
	}
	
	public static Single1 single() {
		// sleep 验证多线程安全,实际使用时去掉
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return single;
	}
}

  懒汉式。使用时创建,线程不安全,加同步。

public class Single2 {

	private static Single2 single = null;
	
	private Single2() {
		
	}
	
	public static synchronized Single2 single() {
		
		if (single == null) {
			// sleep 验证多线程安全,实际使用时去掉
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			single = new Single2();
		}
		
		return single;
	}
}

  多线程验证单例模式只创建了一个实例对象。

// 线程
public class MyThread extends Thread {

	public MyThread() {
		
	}
	
	@Override
	public void run() {
		
		Single1 single1 = Single1.single();
		
		System.out.println(single1);
		
		Single2 single2 = Single2.single();
		
		System.out.println("single2 " + single2);
		
	}
}

//
public class Test1 {

	public Test1() {
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		MyThread t3 = new MyThread();
		MyThread t4 = new MyThread();
		
		// 打印地址相同
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

  枚举。

// 定义枚举
public enum MyEnum {
	EMAN,EWOMAN,ENOT   
}

//
public class Test {
		
	public static void main(String[] args) {
		
		MyEnum enum1 = MyEnum.EWOMAN;
		switch (enum1) {
		case EMAN:
			System.out.println("男神");
			break;
		case EWOMAN:
			System.out.println("女神");
			break;
		case ENOT:
			System.out.println("未知");
			break;
		default:
			break;
		}
	}
}

  注解。注解(Annotation)是代码里的特殊标记, 程序可以读取注解,一般用于替代配置文件。
  开发人员可以通过注解告诉类如何运行。
  在 Java 技术里注解的典型应用,可以通过反射技术去得到类里面的注解,以决定怎么去运行类。
  常见注解。@Override,继承;@Deprecated,标注过时的类和方法。
  定义注解使用 @interface 关键字,注解中只能包含属性。


//
//@interface:定义注解类里面都是属性
@Retention(RetentionPolicy.RUNTIME)  //定义元注解:注解的注解
@Target(ElementType.METHOD) //通过 Method 类型去执行的
public @interface MyAnnotation {
	String name();  //注解类的属性定义
	int age() default 33;   //int age = 33;

	// Class c() default Object.class;   //定义Class类型
	
	// MyEnum enum1();  //定义枚举类型
	
	// MyAnnotation annotation();  //定义注解类型
	
	// int[] as();   //一维数组
}

//
public class Person {
	@MyAnnotation(name = "zsf",age = 99)
	public void show() {
		System.out.println("show....");
	}
}

//
public class Test {
	public static void main(String[] args) throws NoSuchMethodException, SecurityException {
		//通过反射及技术,给注解类中的属性赋值,和取值
		Class c = Person.class;  //得到反射对象
		Method method = c.getMethod("show");  //在show方法中给注解了赋值
		
		MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);  //传注解类对象,获取注解对象
		
		System.out.println(annotation.name());  //取出注解的值
		System.out.println(annotation.age());
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值