类的对象:基于某个类 new 出来的对象,也称为实例对象。
类对象:类加载的产物,封装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法) 。
注意:每个类加载到内存都会生成一个唯一的类对象
- 通过类的对象,获取类对象。
Student s = new Student();
Class c = s.getClass();
- 通过类名获取类对象。
Class c = 类名.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对象的方法获取表示类成员的各种对象(比如Constructor、Method、Field等),实现反射各种应用。
案例演示:反射操作。
Person类:
public class Person implements Serializable,Cloneable{
//姓名
private String name;
//年龄
private int age;
public Person() {
System.out.println("无参构造执行了...");
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
System.out.println("带参构造方法执行了...");
}
//吃
public void eat() {
System.out.println(name+"正在吃东西......");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
//带参的方法
public void eat(String food) {
System.out.println(name+"开始吃...."+food);
}
//私有的方法
private void privateMethod() {
System.out.println("这是一个私有方法");
}
//静态方法
public static void staticMethod() {
System.out.println("这是一个静态方法");
}
}
TestPerson类:
public class TestPerson {
public static void main(String[] args) throws Exception {
//调用测试以下方法
//代码略
}
//获取类对象的三种方式
public static void getClazz() throws Exception {
//1使用对象获取类对象
Person zhangsan=new Person();
Class<?> class1=zhangsan.getClass();
System.out.println(class1.hashCode());
//2使用类名.class属性
Class<?> class2=Person.class;
System.out.println(class2.hashCode());
//3使用Class的静态方法[推荐使用]
Class<?> class3=Class.forName("com.qf.chap17_1.Person");
System.out.println(class3.hashCode());
}
//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
}
}
- 一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
- 可以简单理解为特定问题的固定解决方法。
- 在Gof的《设计模式》书中描述了23 种设计模式。
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、重用性。
开发中有一个非常重要的原则“开闭原则”,对拓展开放、对修改关闭。
工厂模式主要负责对象创建的问题。
可通过反射进行工厂模式的设计,完成动态的对象创建。
案例演示:
IUsb接口:
package com.qfedu.pattern;
//工厂模式:提供usb 接口
public interface IUsb {
void service();
}
MouseImpl类:
package com.qfedu.pattern;
//鼠标
public class MouseImpl implements IUsb {
@Override
public void service() {
System.out.println("鼠标业务逻辑.....");
}
}
> FanImpl类:
package com.qfedu.pattern;
public class FanImpl implements IUsb {
@Override
public void service() {
System.out.println("风扇的业务逻辑......");
}
}
KeyWordImpl类:
package com.qfedu.pattern;
public class KeyWordImpl implements IUsb {
@Override
public void service() {
System.out.println("键盘的业务逻辑.....");
}
}
UsbFactory类:
package com.qfedu.pattern;
//usb对象的工厂:用来生产对象
public class UsbFactory {
//创建对象
/**
*
* @param type 类的全限定路径名
* @return
*/
public IUsb createUsb(String type) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//1获取class
Class<?> usbClass = Class.forName(type);
//2. 利用class 创建对象,并强转
IUsb usb = (IUsb) usbClass.newInstance();
return usb;
}
}
Test测试类:
package com.qfedu.pattern;
public class Test {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
//1 创建工厂对象
UsbFactory usbFactory = new UsbFactory();
//2.调用方法创建Iusb对象
String type = "com.qfedu.pattern.MouseImpl";
IUsb usb = usbFactory.createUsb(type);
//3.多态情况下,:调用重写方法
usb.service();
}
}