第一种方式:getClass
getClass获取类首先需要有实例化对象
Date date = new Date();
Class<?> cls = date.getClass();
System.out.println(cls.getName());
第二种方式:.class
.class获取类不需要有实例化对象,但是需要完整类名
Class<?> cls2 = java.util.Date.class;
System.out.println(cls2.getName());
第三种方式:.forName()
调用.forName()需要有完整的类名
Class<?> cls3 = Class.forName("java.util.Date");
System.out.println(cls3.getCanonicalName());
运行结果:
学了上面的三种主要获取类方式,那么来实践玩玩吧
把之前写的工厂方法模式拿出来看看存在的问题,还没看的或者有兴趣的可以看看,当然不看也行,因为我这里会重新敲一遍工厂模式(为什么要重新敲呢?相当于一个简单的重构吧,让代码更健壮一点点,哈哈…)
好了,链接放就这,然后来看看下面的问题
简单工厂模式里的工厂类(也是静态工厂模式):每次出新的手机牌子就需要修改工厂类违反开闭原则
工厂方法模式呢?看看消费者类获取手机需要new,我们都知道解决耦合的关键是取消new,因为new是耦合的最大元凶,所以我们接下来用反射来帮助我们解决设计上的缺陷。
来,利用反射对工厂模式解耦操作!
Phone接口
public interface Phone {
void getBrand();
}
Meizu品牌类
public class Meizu implements Phone {
@Override
public void getBrand() {
System.out.println("魅族");
}
}
Xiaomi品牌类
public class Xiaomi implements Phone {
@Override
public void getBrand() {
System.out.println("小米");
}
}
PhoneFactory工厂类
利用最开始讲的反射三种获取对象之一的Class.forName(传入完整的包类名)找到它的类,然后使用newInstance()方法反射的对象实例化
public class PhoneFactory {
public static Phone getInstance(String orgin) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class<?> cls = Class.forName(orgin);
Phone brand = (Phone)cls.newInstance();
return brand;
}
}
Customer 消费者类,直白一点说就是可以传值了,而无需用new写死
public class Customer {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
PhoneFactory.getInstance("Factory.Xiaomi").getBrand();
PhoneFactory.getInstance("Factory.Meizu").getBrand();
}
}
运行结果:
可以看到上面代码可以说和静态工厂模式一样,只不过工厂模式利用了反射机制,不再只是用new关键字而是用反射机制来。
最后
实践一波后会发现,对象实例化不再是单独用new来,反射也是可以完成的(当然反射还是需要考虑到性能的,这是后话,到时可以一起来探究一下原理),当然这不表示new会完全被取代,在一些开发中也会经常用到new这个关键字