什么是java反射机制?
1、当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。我们认为java并不是动态语言,但是它却有一个非常突出的动态相关机制,俗称:反射。
IT行业里这么说,没有反射也就没有框架,现有的框架都是以反射为基础。在实际项目开发中,用的最多的是框架,填的最多的是类,反射这一概念就是将框架和类揉在一起的调和剂。所以,反射才是接触项目开发的敲门砖。
2、java中的new方法是静态加载,因为new方法是在编译阶段就会检查,而不是在运行阶段。反射是可以在运行时创建对象,调用对象的方法、变量等。
3、Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
例如:
1 package service.impl; 2 3 public class Test { 4 5 public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException { 6 F f = new F(); 7 // 第一种表达方式 8 Class c1 = F.class;// 这种表达方式同时也告诉了我们任何一个类都有一个隐含的静态成员变量class 9 // 第二种表达方式 10 Class c2 = f.getClass();// 这种表达方式在已知了该类的对象的情况下通过getClass方法获取 11 // 第三种表达方式 12 Class c3 = Class.forName("service.impl.F");// 类的全称 13 14 System.out.println(c1.getName()); 15 System.out.println(c2.getName()); 16 System.out.println(c3.getName()); 17 F temp = (F) c1.newInstance();//这里可以是c1/c2/c3 18 System.out.println(temp.f); 19 temp.save(); 20 } 21 } 22 23 class F { 24 public String f = "test"; 25 26 public void save() { 27 System.out.println("save..."); 28 } 29 }
运行结果:
service.impl.F
service.impl.F
service.impl.F
test
save...
动态加载:
如何动态加载一个类呢?
首先我们需要区分什么是动态加载?什么是静态加载?我们普遍认为编译时刻加载的类是静态加载类,运行时刻加载的类是动态加载类。
例如:
1 Class A{ 2 Public static void main(String[] args){ 3 if("B".equal(args[0])){ 4 B b=new B(); 5 b.start(); 6 } 7 if("C".equal(args[0])){ 8 C c=new C(); 9 C.start(); 10 } 11 } 12 }
上面程序编译时会报错,当我们直接在cmd使用javac访问A.java类的时候,就会抛出问题:
但是如果我们动态加载就可以满足(参数不为“B”或者“C”时候,本应该可以运行)
如:
1 package service.impl; 2 3 public class Test2 { 4 5 public static void main(String[] args) throws InstantiationException, IllegalAccessException { 6 7 Class b = null; 8 try { 9 b = Class.forName("service.impl.B"); 10 } catch (ClassNotFoundException e) { 11 System.err.println("something is wrong!!!"); 12 e.printStackTrace(); 13 } 14 Stand stand = (Stand)b.newInstance(); 15 stand.start(); 16 17 } 18 } 19 20 interface Stand{ 21 void start(); 22 } 23 24 class B implements Stand{ 25 26 public void start() { 27 System.out.println("B...start"); 28 } 29 30 } 31 32 class C implements Stand{ 33 34 public void start() { 35 System.out.println("C...start"); 36 } 37 38 }
运行结果:
B...start
如果以后想用某一个类,不需要重新编译,只需要实现这个标准的接口即可。只需要动态的加载新的东西就行了。
这就是动态加载类