Java核心技术

Java核心技术(1)

一、Java反射机制

1.1、反射的机制

1、反射机制的作用:

  •   反编译:.class-->.java
  •   通过反射机制访问java对象的属性,方法,构造方法等;

2、反射机制的优点与缺点

为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念:

    静态编译:在编译时确定类型,绑定对象,即通过。

   动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。

    一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中,它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功能。它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。

3、应用场景:

  • l  反射机制是很多Java框架的基石

            在Java类里面解析xml或properties里面的内容,得到一个字符串,然后用反射机制,根据这个字符串获得某个类的Class实例,这样就可以动态配置一些东西,不用每一

            次都要在代码里面去new或者做其他的事情,以后要改的话直接改配置文件,代码维护起来就很方便了。

  • l  当你做一个软件可以安装插件的功能,你连插件的类型名称都不知道,你怎么实例化这个对象呢?因为程序是支持插件的(第三方的),在开发的时候并不知道。所以无法在代码中 New出来 ,但反射可以,通过反射,动态加载程序集,然后读出类,检查标记之后再实例化对象,就可以获得正确的类实例。
  • l  在编码阶段不知道那个类名,要在运行期从配置文件读取类名, 这时候就没有办法硬编码new ClassName(),而必须用到反射才能创建这个对象.反射的目的就是为了扩展未知的应用。当你不知道要创建什么类型的对象时,使用在运行时提供类的完整路径的方式来生成类的实例时, 例如: 

          在struts中对messageResources引用的生成中,使用到工厂方法的模式,对于他所要使用的工厂,他采用的是factoryClass参数来生成工厂,之后使用这个工厂的实例来生成messageResources对象。 这其中就使用到了使用reflect产生类的实例。 

          当对象的方法只有在运行时才知道那些方法被调用,那些方法不用调用时,且方法遵循一定的规律生成,而且方法很对,比如100个。

1.2、Java类加载器与反射包

1.2.1、java类加载器

1、Java 3中类加载器

  • l  引导类加载器(Bootstrap ClassLoader )它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。
  • l  扩展类加载器(Extension ClassLoader )它用来加载 Java 的扩展库,一般对应的是jre\lib\ext目录中的类
  • l  系统类加载器(system class loader) 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器,一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。

2、应用实例

//类加载器加载类的用法
ClassLoader loader= ClassLoader.getSystemClassLoader();
Class<User> classUser=(Class<User>) loader.loadClass("com.data.User");
User user=classUser.newInstance();

//用Class加载类
Class<?> cl=Class.forName("com.data.User");
User user=(User) cl.newInstance();

3、ServiceLoader的用法

ServiceLoader通常用来动态加载实现同一个接口的若干类,配置文件通常在src/META-INF/services下的配置文件。如图:

      
ClassLoader loader=Thread.currentThread().getContextClassLoader();
		ServiceLoader<Person> serviceLoader=ServiceLoader.load(Person.class, loader);
		Iterator<Person> interator=serviceLoader.iterator();
		while(interator.hasNext()){
			Person p=interator.next();
			p.print();
		}

1.2.2、Java反射包

1、java.lang.reflect反射包中主要包含以下几类:


java.lang.reflect.Constructor;

java.lang.reflect.Field;       

java.lang.reflect.Method;

java.lang.reflect.Modifier;

2、反射包应用示例

1)获取构造方法及参数

java.lang.reflect.Constructor

@Test
	public void testConstructor() throws ClassNotFoundException{
		Class<?> user = Class.forName("com.data.User");
		Constructor<?> cons[] = user.getConstructors();//获取一个类中所有的构造方法
		for (int i = 0; i < cons.length; i++) {
            Class<?> p[]=cons[i].getParameterTypes();//获取构造方法的参数列表:参数类型
            System.out.print("构造方法:  ");
            int mo=cons[i].getModifiers();	//获取构造方法的修饰符:public private protected			
            System.out.print(Modifier.toString(mo)+" ");
            System.out.print(cons[i].getName());
            System.out.print("(");
            for(int j=0;j<p.length;++j){
                System.out.print(p[j].getName()+" arg"+i);
                if(j<p.length-1){
                    System.out.print(",");
                }
            }
            System.out.println("){}");
		}
	}

2)获取类的方法及其类型

@Test
	public void testMethod() throws ClassNotFoundException{
		Class<?> user = Class.forName("com.data.User");
		Method method[]=user.getMethods();//获取类中包含的方法(不包含构造方法)
		 for(int i=0;i<method.length;++i){
	            Class<?> returnType=method[i].getReturnType();//获取方法的返回类型
	            Class<?> para[]=method[i].getParameterTypes();//获取方法的参数类型
	            int temp=method[i].getModifiers();//获取方法的修饰符
	            System.out.print(Modifier.toString(temp)+" ");
	            System.out.print(returnType.getName()+"  ");
	            System.out.print(method[i].getName()+" ");
	            System.out.print("(");
	            for(int j=0;j<para.length;++j){
	                System.out.print(para[j].getName()+" "+"arg"+j);
	                if(j<para.length-1){
	                    System.out.print(",");
	                }
	            }
	            Class<?> exce[]=method[i].getExceptionTypes();//获取方法的异常类型
	            if(exce.length>0){
	                System.out.print(") throws ");
	                for(int k=0;k<exce.length;++k){
	                    System.out.print(exce[k].getName()+" ");
	                    if(k<exce.length-1){
	                        System.out.print(",");
	                    }
	                }
	            }else{
	                System.out.print(")");
	            }
	            System.out.println();
	        }
	}

输出结果:
public java.lang.String  getName ()
public void  setName (java.lang.String arg0)
public void  print ()
public void  setAge (int arg0)
public int  getAge ()
public final void  wait (long arg0,int arg1) throws java.lang.InterruptedException 
public final native void  wait (long arg0) throws java.lang.InterruptedException 
public final void  wait () throws java.lang.InterruptedException 
public boolean  equals (java.lang.Object arg0)
public java.lang.String  toString ()
public native int  hashCode ()
public final native java.lang.Class  getClass ()
public final native void  notify ()
public final native void  notifyAll ()
3)获取类的成员变量
@Test

     publicvoid testField() throws ClassNotFoundException{

         Class<?>user = Class.forName("com.data.User");

         Field[]field = user.getDeclaredFields();

         for (int i = 0; i < field.length; i++) {

            // 权限修饰符

            int mo = field[i].getModifiers();

            String priv = Modifier.toString(mo);

            // 属性类型

            Class<?> type =field[i].getType();

            System.out.println(priv + " " + type.getName() + " "

                    + field[i].getName() + ";");

        }
     }
4)  invoke
Class<?> user = Class.forName("com.data.User");
		Method method =user.getMethod("setAge",int.class);
		User u=(User) user.newInstance();
		method.invoke(u, 11);
		u.print();
执行invoke时,相当于执行u.setAge(11)方法



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在软件设计里到处都是模式,框架。有次朋友问什么是模式?我也在学习中,就我的学习经验,给出以下小结。(注意:个人观点,仅供参考,欢迎指正。)??1.什么是模式???模式,即pattern。其实就是解决某一类问题的方法论。你把解决某类问题的方法总结归纳到理论高度,那就是模式。??Alexander给出的经典定义是:每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心。通过这种方式,你可以无数次地使用那些已有的解决方案,无需在重复相同的工作。??模式有不同的领域,建筑领域有建筑模式,软件设计领域也有设计模式。当一个领域逐渐成熟的时候,自然会出现很多模式。??什么是框架???框架,即framework。其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。简单说就是使用别人搭好的舞台,你来做表演。而且,框架一般是成熟的,不断升级的软件。??2.为什么要用模式???因为模式是一种指导,在一个良好的指导下,有助于你完成任务,有助于你作出一个优良的设计方案,达到事半功倍的效果。而且会得到解决问题的最佳办法。??为什么要用框架???因为软件系统发展到今天已经很复杂了,特别是服务器端软件,设计到的知识,内容,问题太多。在某些方面使用别人成熟的框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑设计。而且框架一般是成熟,稳健的,他可以处理系统很多细节问题,比如,事物处理,安全性,数据流控制等问题。还有框架一般都经过很多人使用,所以结构很好,所以扩展性也很好,而且它是不断升级的,你可以直接享受别人升级代码带来的好处。??框架一般处在低层应用平台(如J2EE)和高层业务逻辑之间的中间层。??软件为什么要分层???为了实现“高内聚、低耦合”。把问题划分开来各个解决,易于控制,易于延展,易于分配资源…总之好处很多啦:)。??3.以下所述主要是JAVA,J2EE方面的模式和框架:??常见的设计模式有什么???首先,你要了解的是GOF的《设计模式--可复用面向对象软件的基础》一书(这个可以说是程序员必备的了),注意:GOF不是一个人,而是指四个人。它的原意是Gangs Of Four,就是“四人帮”,就是指此书的四个作者:Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides。这本书讲了23种主要的模式,包括:抽象工厂、适配器、外观模式等。??还有其他的很多模式,估计有100多种。??软件设计模式太多,就我的理解简单说一下最常见的MVC模式。??MVC模式是1996年由Buschmann提出的:??模型(Model):就是封装数据和所有基于对这些数据的操作。??视图(View):就是封装的是对数据显示,即用户界面。??控制器(Control):就是封装外界作用于模型的操作和对数据流向的控制等。??另外:??RUP(Rational Unified Process)软件统一过程,XP(Extreme Programming)极端编程,这些通常被叫做“过程方法”,是一种软件项目实施过程的方法论,它是针对软件项目的实施过程提出的方法策略。也是另一个角度的模式。??4.常见的JAVA框架有什么???WAF:??全称:WEB APPLICATION FRAMEWORK??主要应用方面:EJB层,(WEB层也有,但是比较弱)。??主要应用技术:EJB等??出处:http://java.sun.com/blueprints/code/index.html??简述:这是SUN在展示J2EE平台时所用的例子PetStore(宠物商店系统)里面的框架。是SUN蓝皮书例子程序中提出的应用框架。它实现了 MVC和其他良好的设计模式。SUN的网站上有技术资料,最好下载PetStore来研究,WEBLOGIC里自带此系统,源码在beaweblogic700samplesserversrcpetstore。这是学习了解J2EE的首选框架。??免费。??Struts:??主要应用方面:WEB层。??主要应用技术:JSP,TagLib,JavaBean,XML等??出处:http://jakarta.apache.org/struts/index.html??简述:这是APACHE的开源项目,目前应用很广泛。基于MVC模式,结构很好,基于JSP。Jbuilder8里已经集成了STRUTS1.02的制作。??免费。??简述WAF+STRUTS结合的例子:WEB层用STRUTS,EJB层用WAF:??JSP(TagLib)——>ActionForm——>Action ——> Event——>EJBAction——>EJB ——>DAO——>Database JSP(TagLib)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值