Java 反射
类对象
类的对象:基于某个类 new 出来的对象,也成为实例对象 类对象:类加载的产物,分装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法)
每个类加载到内存中都会生成一个唯一的类对象‘
获取类对象
- 通过类的对象,获取类对象
Student s = new Student();
Class<? extend Student> c = s.getClass();
- 通过类名获取类对象
Class<Student> c = Student.class
- 通过静态方法获取类对象
Class<?> c = Class.forName("包名.类名")
反射通用操作
| ⽅法名 | 描述 |
|---|---|
| public String getName() | 获取类的完全名称 |
| public Package getPackage() | 获取包信息 |
| public Class<? super T> getSuperclass() | 获取⽗类 |
| public Class<?>[] getInterfaces() | 获取实现⽗接⼝ |
| public Field[] getFields() | 获取字段信息 |
| public Method[] getMethods() | 获取⽅法信息 |
| public Constructor<?>[] getConstructors() | 获取构造⽅法 |
| public T newInstance() | 反射创建对象 |
使用反射机制获取类对象,并使用Class对象的方法获取表示类成员的各种对象,实现反射各种应用。
设计模式
工厂方法模式
public abstract class Clothes {
public abstract void prepare();
public abstract void make();
public abstract void box();
}
public class ClothesFactory {
private static Properties properties;
static {
properties = new Properties();
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream("src\clothes.properties");
properties.load(fileInputStream);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
System.out.println("流关闭失败");
}
}
}
}
public static Clothes create(int type) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
String className = properties.getProperty(type + "");
Clothes clothes = null;
if (className != null) {
Class<?> class1 = Class.forName(className);
clothes = (Clothes) class1.newInstance();
if (clothes != null) {
clothes.prepare();
clothes.make();
clothes.box();
}
}
return clothes;
}
}
单例模式
饿汉式
优点:线程安全 缺点:生命周期长,浪费空间
public class SingleInstance {
private static SingleInstance singleInstance = new SingleInstance();
private SingleInstance() {
}
public static SingleInstance getInstance() {
return singleInstance;
}
}
懒汉式
优点:获取对象时才创建对象 缺点:线程不安全
public class SingleInstance2 {
private static volatile SingleInstance2 singleInstance2;
private SingleInstance2() {
}
public SingleInstance2 getSingleInstance2() {
if (singleInstance2 == null) {
synchronized (SingleInstance2.class) {
if (singleInstance2 == null) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
singleInstance2 = new SingleInstance2();
}
}
}
return singleInstance2;
}
}
静态内部类
兼具懒汉式和饿汉式的优点
public class SingleInstance3 {
private SingleInstance3() {
}
private static class Inner {
static SingleInstance3 singleInstance3 = new SingleInstance3();
}
public SingleInstance3 getInstance() {
return Inner.singleInstance3;
}
}
枚举
枚举是一个引用类型,枚举是一个规定了取值范围的数据类型。
- 枚举变量不能使用其他的数据,只能使用枚举中常量赋值,提高程序安全性。
- 定义枚举使用
enum关键字。 - 枚举的本质
- 枚举是一个终止类,并继承Enum抽象类。
- 枚举中常量是当前类型的静态常量。
public enum Gender {
MALE,FEMALE
}
- 枚举中必须要包含枚举常量,也可以包含属性、方法、私有构造方法。
- 枚举常量必须在前面,多个常量之间使用逗号隔开,最后分号可写可不写。
注解
注解(Annotation):是代码里的标记,程序可以读取注解,一般用于代替配置文件。 开发人员可以通过注解告诉类如何运⾏。 在Java技术⾥注解的典型应⽤是:可以通过反射技术去得到类⾥⾯的注解,以决定怎么去运⾏类。
定义注解
定义注解使⽤@interface关键字,注解中只能包含属性。
public @interface MyAnnotation {
String name() default "张三";
int age();
}
注解属性类型
- String类型
- 基本数据类型
- Class类型
- 枚举类型
- 注解类型
- 以上类型的一维数组
元注解
元注解:⽤来描述注解的注解。
@Retention:用于于指定注解可以保留的域。
- RetentionPolicy.CLASS:
- 注解记录在class⽂件中,运⾏Java程序时, JVM不会保留,此为默认值。
- RetentionPolicy.RUNTIME:
- 注解记录在 class⽂件中,运⾏Java程序时,JVM会保留,程序可以通过反射获取该注释
- RetentionPolicy.SOURCE:
- 编译时直接丢弃这种策略的注释。
@Target
- 指定注解用于修饰类的哪个成员
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {Element.METHOD})
public @interface PersonInfo {
String name();
int age();
String sex();
}