底层代码可见性控制

Java提供了private,public,protected和package private(无修饰符)这四种访问控制级别,不过这仅仅提供了底层的OO数据封装特性。包这个概念确实是起到了分割代码的作用,但是如果包中的代码需要对包外可见,那么必须设置为public(或者protected,如果是使用了继承的话)。 这样的话就可能出现一个问题:

首先大家看看下面的例子,其中有三个java文件: 
org.serc.helloworld.Hello.java:定义了一个接口

package org.serc.helloworld; 

public interface Hello {
void sayHello();
}
org.serc.helloworld.impl.HelloImpl.java:实现了Hello接口
package org.serc.helloworld.impl; import org.serc.helloworld.Hello; public class HelloImpl implements Hello{
final String helloString; public HelloImpl(String helloString){
this.helloString=helloString;
} public void sayHello(){
System.out.println(this.helloString);
}
} org.serc.helloworld.main.Main.java
package org.serc.helloworld.main; import org.serc.helloworld.Hello;
import org.serc.helloworld.HelloImpl; public class Main{
final StringhelloString; public static void main(String[] args){
Hello hello = new HelloImpl(“Hello,SERC!”);
hello.sayHello();
}
}

这三个文件分别在不同的包中。按理说,HelloImpl这个实现细节是不应该暴露给其他包的,但是从Main.java的main方法中我们可以明显的看出,为了创建Hello 的实例,我们不得不引入HelloImpl类,但是HelloImpl作为接口的实现细节,是不应该暴露给使用者的,这违反了封装的原则,显然不太好。

但是,如果我们不想让HelloImpl暴露出来的话,就需要做额外的工作来保证“既隐藏了实现细节,又能简单的创建一个实现了Hello接口的实例”。达到这一目的的方法不止一种(比如工厂模式),有些至今也是很常用的,但是这增加了与应用本身功能无关的多余工作,想想如果你每次想开发一个应用都要为了达到上述目的而做出多余工作,不得不说是有点繁琐的,所以这可以说是Java的一大局限。

2.2.2 classpath的局限

我们在classpath中加入jar包的时候,只是简单的给出文件路径,而这个jar包的版本和一致性,它所依赖的jar包是什么,我们都无法在classpath中明确的设置或是从classpath中看出这些属性。 
并且classpath中的jar包是按序加载的,例如:

classpath=c:\servlet2.2\servlet.jar;c:\servlet2.3\servlet.jar,

那么在实际应用的过程中,Java让你使用的是servlet2.2,而不是servlet2.3。这种情况下我们还能看出来使用的是哪个版本,如果在大型系统中大家分开开发的时候各用各的servlet包,并且版本号不一样,那么在最后将开发结果合并的时候,到时候用的是哪个版本的servlet包就很难搞清楚了,也就说不可控性是比较强的。 
即使classpath能注意到版本的问题,也没法精确指出依赖。试着回想你在设置classpath的过程中出现过情况:在你以为classpath已经设置完毕以后,你尝试启动程序,结果虚拟机抛出异常告诉你缺包,然后你再加上你觉得缺少的那些包,然后再启动程序,如此反复直到虚拟机不运行到缺包异常为止。

OSGi对这些局限性的改善

对于上一小节提到的Java的局限,在OSGi中都得到了很好的解决。

·  包的可见性:OSGi通过引入包的可见性机制,能够完全控制一个包中的代码对哪些模块可见,而不仅仅局限于无差别的可见性,从而完善了Java的代码访问控制机制。

·  包的版本: OSGi通过为包增加版本信息,可以精确控制代码的依赖,保证代码的版本一致性,弥补了classpath的缺点。

OSGi 学习之路(4) - osgi的模块化 java在模块化的局限性的更多相关文章

  1. osgi实战学习之路:3. osgi分层概念及相互合作demo

    源码下载 分层: modual: 主要作用于包级管理与共享代码 lifecycle: 主要作用于执行期间的模块管理与訪问osgi底层框架 service: 主要作用于多模块之间的相互通信 demo: ...

  2. Java学习之路(一)了解Java

    Java“白皮书”的关键术语 1)简单性 相对于C++:没有头文件.指针运算.结构.联合.操作符重载.虚基类. 另一方面是小:java微型版(Java Micro Edition)用于嵌入式设备 2) ...

  3. HBase 学习之路(六)——HBase Java API 的基本使用

    一.简述 截至到目前(2019.04),HBase 有两个主要的版本,分别是1.x 和 2.x ,两个版本的Java API有所不同,1.x 中某些方法在2.x中被标识为@deprecated过时.所 ...

  4. Hadoop 学习之路(七)—— HDFS Java API

    一. 简介 想要使用HDFS API,需要导入依赖hadoop-client.如果是CDH版本的Hadoop,还需要额外指明其仓库地址: <?xml version="1.0" ...

  5. Redis学习之路(四)Redis-cluster java api操作

    import redis.clients.jedis.HostAndPort;import redis.clients.jedis.JedisCluster;import java.util.Hash ...

  6. osgi实战学习之路:8. Service-3之ServiceTracker

    通过ServiceTracker能够对查找的Service进行扩展 以下的demo引入装饰器模式对Service进行日志的扩展 demo: Provider student-manage/Activa ...

  7. osgi实战学习之路:2. maven+maven-bundle-plugin+karaf搭建osgi之HelloWorld

    环境准备: jdk版本号 jdk:1.7 karaf: 版本号:apache-karaf-3.0.1 下载地址: http://pan.baidu.com/s/1qWM4Y1u http://kara ...

  8. osgi实战学习之路:6. Service-1

    什么是Service? 它是注冊到osgi的一个java对象 Service注冊: 通过BundleContext::registerService(java.lang.String[] clazze ...

  9. OSGI学习总结

    最近的一项研究了解了一下OSGI技术,感觉OSGI尽管有一定的学习难度.可是终于掌握和推广之后将是一项对系统开发比較实用的技术.在此和大家分享一下自己的感悟. 1.什么是OSGI OSGI直译为&qu ...

随机推荐

  1. TensorFlow文本与序列的深度模型

    TensorFlow深度学习笔记 文本与序列的深度模型 Deep Models for Text and Sequence 转载请注明作者:梦里风林Github工程地址:https://github. ...

  2. 几个BCB例子

    http://blog.163.com/tab_98/blog/static/11924097201511274543737/

  3. Hadoop实战实例

    Hadoop实战实例        Hadoop实战实例        Hadoop 是Google MapReduce的一个Java实现.MapReduce是一种简化的分布式编程模式,让程序自动分布 ...

  4. C#操作Excel(读/写)

    http://www.cnblogs.com/litianfei/archive/2008/03/21/1116906.html 写的很详细 一.操作Excel 首先导出Excel (1)示例: // ...

  5. PHP - 发送短信

    1.购买服务 我购买的是在百度进行推广的API服务.按照要求进行购买就好,之后获取自己的apikey. 2.将提供的代码修改后集成到项目中: <?php /** * * * 发送短信 * * * ...

  6. CheckBox控件

    前台代码: <asp:CheckBox ID="CheckBox1" runat="server" Text ="苹果"/> & ...

  7. C#反射 入门学习 01

    前言     获取方法的相关信息的两种形式 反射是一种允许用户获得类信息的C#功能,Type对象映射它代表的底层对象: 在.Net 中, 一旦获得了Type对象,就可以使用GetMethods()方法 ...

  8. inet_addr() inet_ntoa() inet_pton inet_ntop sockaddr_in

    inet_addr() 简述:将一个点间隔地址转换成一个in_addr.#include <winsock.h>unsigned long PASCAL FAR inet_addr( co ...

  9. 判断程序是否在VMWare内运行

    现在有许多用户都喜欢用虚拟机来测试他们的软件,以避免对真实机器环境造成损害.但是在虚拟机中,有些功能是受限,甚至不可能完成的,因此,需要在程序中判断虚拟机的环境,如果程序在虚拟机内运行,则就要把虚拟机 ...

  10. C语言中 移位操作运算

    移位规律: 左移时总是移位和补零.右移时无符号数是移位和补零,此时称为逻辑右移;而有符号数大多数情况下是移位后补最左边的位(也就是补最高有效位),移几位就补几位,此时称为算术右移.(其实跟扩展逻辑一样 ...