反射机制(实例化Class)对象
反,就是利用对象找到对象的出处
Object类中有一个方法,getClass()
Date date = new Date(); System.out.println(date.getClass());
结果:
class java.util.Date
Class类对象实例化
Class 是一个类,这个类是反射操作的源头。所有的反射都要从此类开始进行。
这个类有三个实例化方式。
1.调用 Object类中的getClass()方法
Date date = new Date(); Class <?> cl = date.getClass(); System.out.println(cl);
2.类.class;
Date date = new Date(); Class <?> cl =Date.class; System.out.println(cl);
3.(重点)调用class类提供的方法:
实例化Class对象
public static Class<?> forName(String className)throws ClassNotFoundException
接受String
package cn; public class Test { public static void main(String[] args) throws Exception{ Class <?> cls = Class.forName("java.util.Date") ; System.out.println(cls); } }
此时可以不用 import 语句导入一个明确的类。
************************************************************
现在利用反射实例化对象操作
package cn; class Book { public Book() { System.out.println("********************"); } } public class Test { public static void main(String[] args) throws Exception{ Class <?> cl = Class.forName("cn.Book") ; Object obj = cl.newInstance() ; Book book = (Book) obj ; } }
有了反射之后,不再需要new完成了
反射也可以完成,但是这个并没有表示new被完全取代了。
new是造成耦合的最大元凶。
举个栗子:
工厂设计模式:
package cn; interface Fruit{ public void eat() ; } class Apple implements Fruit{ public void eat() { System.out.println("吃苹果") ; } } class Factory{ public static Fruit getInstance(String className){ if("apple".equals(className)){ return new Apple() ; } return null ; } } public class Test { public static void main(String[] args) throws Exception{ Fruit f = Factory.getInstance("apple") ; f.eat() ; } }
如果现在要加一个橘子类,那么就要修改工厂的函数。
但是现在使用反射机制就可以避免修改这个类
package cn; interface Fruit{ public void eat() ; } class Apple implements Fruit{ public void eat() { System.out.println("吃苹果") ; } } class Factory{ public static Fruit getInstance(String className){ Fruit f = null ; try{ f= (Fruit) Class.forName(className) .newInstance(); } catch (Exception e){} return f ; } } public class Test { public static void main(String[] args) throws Exception{ Fruit f = Factory.getInstance("cn.Apple") ; f.eat() ; } }