类的对象:基于某个类 new 出来的对象,也称为实例对象。
类对象:类加载的产物,封装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法) 。
1.通过类的对象,获取类对象。
- Student s = new Student();
- Class c = s.getClass();
2.通过类名获取。
- Class c = 类名.class;
3.通过静态方法获取类对象。
- Class c=Class.forName(“包名.类名”);
1 常见方法
方法名 | 描述 |
---|---|
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() | 反射创建对象 |
//1 使用反射获取类的名字、包名、父类、接口
public static void reflectOpe1() throws Exception {
//(1)获取类对象 Person
Class> class1=Class.forName("com.qf.chap17_1.Person");
//getName();
System.out.println(class1.getName());
//getPackage();
System.out.println(class1.getPackage().getName());
//getSuperClass();
System.out.println(class1.getSuperclass().getName());
//getInterfaces();
Class>[] classes=class1.getInterfaces();
System.out.println(Arrays.toString(classes));
System.out.println(class1.getSimpleName());
System.out.println(class1.getTypeName());
//2使用反射获取类的构造方法,创建对象
public static void reflectOpe2() throws Exception{
//(1)获取类的类对象
Class> class1=Class.forName("com.qf.chap17_1.Person");
//(2)获取类的构造方法 Constructor
Constructor>[] cons=class1.getConstructors();
for (Constructor> con : cons) {
System.out.println(con.toString());
}
//(3)获取类中无参构造
Constructor> con=class1.getConstructor();
Person zhangsan=(Person)con.newInstance();
Person lisi=(Person)con.newInstance();
System.out.println(zhangsan.toString());
System.out.println(lisi.toString());
//简便方法:类对象.newInstance();
Person wangwu=(Person)class1.newInstance();
System.out.println(wangwu.toString());
//(4)获取类中带参构造方法
Constructor> con2=class1.getConstructor(String.class,int.class);
Person xiaoli=(Person)con2.newInstance("晓丽",20);
System.out.println(xiaoli.toString());
}
//3使用反射获取类中的方法,并调用方法
public static void reflectOpe3() throws Exception{
//(1)获取类对象
Class> class1=Class.forName("com.qf.chap17_1.Person");
//(2)获取方法 Method对象
//2.1getMethods() 获取公开的方法,包括从父类继承的方法
//Method[] methods=class1.getMethods();
//2.2getDeclaredMethods() 获取类中的所有方法,包括私有、默认、保护的 、不包含继承的方法
Method[] methods=class1.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.toString());
}
//(3)获取单个方法
//3.1eat
Method eatMethod=class1.getMethod("eat");
//调用方法
//正常调用方法 Person zhangsan=new Person(); zhangsan.eat();
Person zhangsan=(Person)class1.newInstance();
eatMethod.invoke(zhangsan);//zhangsan.eat();
System.out.println("------------------");
//3.2toString
Method toStringMethod=class1.getMethod("toString");
Object result=toStringMethod.invoke(zhangsan);
System.out.println(result);
System.out.println("-------------------");
//3.3带参的eat
Method eatMethod2=class1.getMethod("eat", String.class);
eatMethod2.invoke(zhangsan, "鸡腿");
//3.4获取私有方法
Method privateMethod=class1.getDeclaredMethod("privateMethod");
//设置访问权限无效
privateMethod.setAccessible(true);
privateMethod.invoke(zhangsan);
//3.4获取静态方法
Method staticMethod=class1.getMethod("staticMethod");
//正常调用 Person.staticMethod
staticMethod.invoke(null);
}
//4使用反射实现一个可以调用任何对象方法的通用方法
public static Object invokeAny(Object obj,String methodName,Class>[] types,Object...args) throws Exception {
//1获取类对象
Class> class1=obj.getClass();
//2获取方法
Method method=class1.getMethod(methodName, types);
//3调用
return method.invoke(obj, args);
}
//5使用反射获取类中的属性
public static void reflectOpe4() throws Exception{
//(1)获取类对象
Class> class1=Class.forName("com.qf.chap17_1.Person");
//(2)获取属性(字段) 公开的字段,父类继承的字段
//Field[] fields=class1.getFields();
//getDeclaredFields()获取所有的属性,包括私有,默认 ,包含,
Field[] fields=class1.getDeclaredFields();
System.out.println(fields.length);
for (Field field : fields) {
System.out.println(field.toString());
}
//(3)获取name属性
Field namefield=class1.getDeclaredField("name");
namefield.setAccessible(true);
//(4)赋值 正常调用 Person zhangsan=new Person(); zhangsan.name="张三";
Person zhangsan=(Person)class1.newInstance();
namefield.set(zhangsan, "张三"); //zhangsan.name="张三";
//(5) 获取值
System.out.println(namefield.get(zhangsan));// zhangsan.name
}
}
一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
可以简单理解为特定问题的固定解决方法。
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、重用性。
开发中有一个非常重要的原则“开闭原则”,对拓展开放、对修改关闭。
工厂模式主要负责对象创建的问题。
可通过反射进行工厂模式的设计,完成动态的对象创建。
单例(Singleton):只允许创建一个该类的对象。
public class SingleTon {
private static final SingleTon instance=new SingleTon();
private SingleTon() {}
public static SingleTon getInstance() {
return instance;
}
}
public class SingleTon2 {
// 创建对象
private static SingleTon2 instance = null;
// 私有化构造方法
private SingleTon2() {
}
// 静态方法
public static SingleTon2 getInstance() {
if(instance==null) {//提高执行效率
synchronized (SingleTon2.class) {
if (instance == null) {
instance = new SingleTon2();
}
}
}
return instance;
}
}
public class SingleTon3 {
private SingleTon3() {}
private static class Holder{
static SingleTon3 instance=new SingleTon3();
}
public static SingleTon3 getInstance() {
return Holder.instance;
}
}
枚举是一个引用类型,枚举是一个规定了取值范围的数据类型。
枚举变量不能使用其他的数据,只能使用枚举中常量赋值,提高程序安全性。
定义枚举使用enum关键字。
枚举的本质:
枚举是一个终止类,并继承Enum抽象类。
枚举中常量是当前类型的静态常量。
枚举中必须要包含枚举常量,也可以包含属性、方法、私有构造方法。
枚举常量必须在前面,多个常量之间使用逗号隔开,最后分java号可写可不写。
注解(Annotation):是代码里的特殊标记, 程序可以读取注解,一般用于替代配置文件。
开发人员可以通过注解告诉类如何运行。
在Java技术里注解的典型应用是:可以通过反射技术去得到类里面的注解,以决定怎么去运行类。
定义注解使用@interface关键字,注解中只能包含属性。
常见注解:@Override、@Deprecated
案例:
public @interface MyAnnotation {
//属性(类似方法)
String name() default "张三";
int age() default 20;
}
- String类型
- 基本数据类型
- Class类型
- 枚举类型
- 注解类型
- 以上类型的一维数组
元注解:用来描述注解的注解。
@Retention:用于指定注解可以保留的域。
RetentionPolicy.CLASS: 注解记录在class文件中,运行Java程序时, JVM不会保留,此为默认值。
RetentionPolicy.RUNTIME: 注解记录在 class文件中,运行Java程序时,JVM会保留,程序可以通过反射获取该注释
RetentionPolicy.SOURCE: 编译时直接丢弃这种策略的注释。
@Target:
指定注解用于修饰类的哪个成员。