注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

零点星空

记录零点的思考!

 
 
 

日志

 
 

Java vs C++  

2008-09-10 20:20:38|  分类: IT技术学习 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

1. Java背景
    Java语言最初的设计企图是想用于控制消费性电子产品,比如传呼机,这些都是典型的嵌入设备。Java的设计者企图建立一个简单的、面向对象的、智慧的、已经解译的、强大的、安全的、架构合理的、可移植的、高性能的、多线程的、动态的语言。为使Java对开发者有吸引力,Sun公司融合了类似于C语言的语法和结构。然而不管目标订得如何,Java还是被证明不适合于小型的电子设备,这很大程度上是因为它太大而且速度太慢。应用Java程序所需要的处理能力和内存量,对这类设备来说太昂贵了。
    话又说回来,Sun公司设计Java时最重要的是平台无关及网络集成。一个无须更改就能够在几种不同硬件和软件平台运行的程序,对网络环境(在这种环境中用户希望能够在办公室的任何机器上传、下载和运行程序)来说是一个理想的程序。对想建立通过网络来通信并利用网上资源的分布式程序的开发者来说,一种在任何平台上都有内置的和标准的网络支持的语言是一个大实惠。
    Java设计的本意是要简化C++(原名为olk),但是设计之后竟然首先在嵌入式系统中取得了成功(改名为java),而后其强大的网络功能使其成为网络编程和嵌入式系统中的利器。

 

2. 嵌入式系统以及个人电脑上C++与Java
    C/C++运行效率高,可以对具体的平台进行优化;Java的开发效率高,移植性好。应该根据具体的应用要求,选择合适的开发工具。如果是需要执行效率非常高的应用,比如说图形游戏什么的,当然再困难也要是用C++。但是,如果是一些下载率很高并且升级很快的个人应用软件,用JAVA的优势就比较明显。

 

2.1. Java对比C++优势
2.1.1. 可移植性强
    Java设计者考虑的一个主要问题是程序代码的持久性和可移植性。程序员面临的一个主要问题是,不能保证今天编写的程序明天能否在同一台机器上顺利运行。操作系统升级、处理器升级以及核心系统资源的变化,都可能导致程序无法继续运行。Java设计者对这个问题做过多种尝试,Java虚拟机(JVM)就是试图解决这个问题的。他们的目标是“只要写一次程序,在任何地方、任何时间该程序永远都能运行”。在很大程度上,Java实现了这个目标。
2.1.2. 解释性和高性能
    通过把程序编译为Java字节码这样一个中间过程,Java可以产生跨平台运行的程序。字节码可以在提供Java虚拟机(JVM)的任何一种系统上被解释执行。Java可以在非常低档的CPU上顺利运行。Java确实是一种解释性语言,Java的字节码经过仔细设计,因而很容易便能使用JIT(Just-In Time,或JIT)编译技术将字节码直接转换成高性能的本机代码。Java运行时系统在提供这个特性的同时仍具有平台独立性,因而“高效且跨平台”对Java来说不再矛盾。
2.1.3. 健全性
    Java程序不可能造成计算机崩溃。Java系统仔细检测对内存的每次访问,确认它是合法的,而且不致引起任何问题。不过,即使Java程序也可能有错误。如果出现某种出乎意料之事,程序不会崩溃,而把该例外抛弃。程序会发现这类例外,并加以处理。传统的程序可以访问计算机的全部内存。程序可能(无意识地)修改内存中的任何值,这就会造成问题。Java程序只能访问内存中允许它们访问的那些部分,所以Java程序不可能修改不拟修改的值。在Java的情况下,编程人员不必为内存管理操心。Java系统有一个叫做“无用单元收集器”的内置程序,它扫描内存,并自动释放那些不再使用的内存块。
2.1.4. 小巧性
    由于Java的设计是要在小的计算机上运行,作为一种编程语言来说其系统是相对较小的。它能有效地在4MB以上RAM的PC机上运行。Java翻译器只占用几百KB。这种翻译器对Java的平台无关性和可移植性是可靠的。由于Java很小,它对内存很小的计算机,如基于Java的PC机,以及电视机、烤箱、电话机及家用计算机等,是很理想的。
2.1.5. 可扩展性
    Java程序可与用其它语言编写的现存程序库连接。由于Java数据结构与C的数据结构的类型极为相似,这是相当方便的。最大的问题在于,现有多线程程序库为数不多。Java程序可以声明某些方法是内部的,然后,把这些内部方法映射成软件库所定义的功能,从而动态地链接到虚拟机。
2.1.6. 安全性高
    由于有了JVM,一个Java应用程序与操作系统或硬件完全隔绝,因此计算机病毒或其他作祟的代码就很难获得对设备的控制。虚拟机是主机设备和那些可能难以确定其质量和可靠性的软件之间的一个保护层。
    另外,Java设计者从该语言中去掉了指针变量的概念。Java不能任意访问内存,只能读写有Java内存分配管理系统创建的对象。由于Java编译器所强制的严格的分类机制,从理论上来说,访问那些未分配给程序的内存区域是不可能的。这个限制使得写恶意代码变得非常困难了。当然,这个保护并不完善,有人已经在Java安全模型中找到漏洞,但是,JVM确实提供了一定的保护,使得几乎不可能直接在硬件上运行代码。
2.1.7. 图形功能强大
    JVM包括一个庞大的图形及窗口支持程序包,称为Abstract Windowing Toolkit(AWT)。用AWT,能在应用程序中快速而轻易地创建精致而强大的图形用户界面。对于需要精细的用户界面的嵌入系统来说,AWT能节省大量开发时间,从而使产品更快地走向市场。

 

2.2. Java对比C++的缺点
2.2.1. 速度慢
    为了实现跨平台的软件开发,Java设计了基于虚拟机(JVM,JavaVirture Machine)机制进行程序的编译,确切地说是解释器和编译器相结合,因此在运行速度上比较慢,但是通过这几年的改进,速度已有了大幅提升,目前速度的差异仍然有,但在一般的应用中看起来并不大。根据使用的不同,分为J2SE(Java标准版),J2ME(微系统版,嵌入式系统开发,如手机游戏)和J2EE(企业版,ERP、企业级应用开发)三大版本。
    Java比典型的脚本语言大为有效,但它比C慢20倍。这对大多数应用是可接受的。不久的将来,代码生成器就可供利用了,这将使Java程序几近于用C或C++编写的程序那么快。
    可以用到人们称为“刚好及时”(Just-In Time,或JIT)的编译器,甚至考虑更低级的代码编译器。当然,低级代码编译器会使编译好的程序不能跨平台执行,但同时也带来了速度上的提升。这个速度甚至接近C和C++。
2.2.2. 源代码保护机制不够安全
    在保护源代码方面,java是基于解释一种叫Java字节码的中间代码来运行其程序的,而且Jvm比计算机的微处理器要简单的多,文档也很齐全,结果造成其目标程序很容易被反编译,而且所得代码和其原始代码十分相似,甚至可以一模一样,可读性相当好。这就给Java的代码保护带来了不利。
2.2.3. 语言尚不够成熟
    从标准的程序设计语言角度来看,Java还很年轻,也很粗糙。如果Java不是由一个小组开发的,也许某些错误和疏忽已经被发现和解决了。在Java亮相以后,它立即被用于比原来预期更多的地方。这一切都意味着Java最初的构思和实现,虽然坚实和有用,但在安全、大小和性能几方面仍感欠缺。
2.2.4. 放弃指针
    既是优点又是缺点。指针是很有效的,但要慎重使用。而java是纯面向对象语言,内存操作等都是JVM分配的。放弃指针尽管提高了安全可靠性,但是给开发带来不便。
2.2.5. 缺乏直接硬件接口能力。
    Java缺乏直接同硬件接口的能力。JVM仅仅是一个虚拟的机器,一个对硬件的软件抽象,虚拟机控制与实际硬件的接口,而我们只能和虚拟机打交道。
2.2.6. 垃圾收集的系统开销过大
    Java中的自动内存分配和垃圾收集性能是很实惠的,但是,从实时系统的角度来看,它的问题恰好就在于它是自动的。当垃圾收集进行时,开发者对系统的控制就受限了。因为,垃圾收集运行时,它冻结了系统其余部分的处理。这是因为它必须要在内存中移动对象,并必须在程序再次运行前,更新所有引用(指向)那些对象的程序变量。垃圾收集需要冻结处理的时间,具体取决于内存量和处理器的速度。很显然,这对硬实时系统是无法接受的,甚至极端时对软实时系统也是成问题的。

 

3. Java反编译安全性研究
    上文提到,Java在源代码保护机制不够安全。但要实现java程序的保护,也不是不可能的,经研究和总结,至少有三种实现方式:1、混淆器;2、网络加载重要类;3、加密重要类。

 

3.1. 混淆器
    目前,开发人员使用的比较多的保护代码的方法是用混淆器。混淆器是采用一些方法将类,变量,方法,包的名字改为无意义的字符串;使用非法的字符代替符号;贴加一些代码使反编译软件崩溃;贴加一些无关的指令或永远执行不到的指令等使反编译无法成功或所得的代码可读性很差。
    混淆后,再反编译所仍然能得到源代码,但显然,所得代码与原始代码比,变得难以读懂,代码中多了其他的方法,文件名等信息也被打乱了。并且,把以上代码写进非法的字符中,无法通过编译。
    但是,如果在编写软件时,在软件中写入某些注册信息,或一些简单的算法,通过反编译,还是有可能得到这些信息的,从而未能达到保护软件的目的。反编译器与混淆器之间的斗争是永无止尽的。所以从其他角度去保护java的源代码是很有必要。
    但是这种办法在网上很容易找到相关的软件来重新整理,那么这个混编只能控制一些本来也没有办法动您的软件的人,而对于一些掌握工具的人几乎是透明的

 

3.2. 网络加载重要类
    在Java中提供了一个ClassLoader类,这个类可以让开发者使用类加载器将所需要的Java字节码文件加载到jvm中。通过重写这个类,可以实现从网络通过url加载Java字节码文件。这样,我们就可以把一些重要的,隐秘的class放在网络服务器上,通过口令去检验是否有权限下载该类。从而实现Java代码保护的目的。其次在Java中正好提供了URLClassLoader这个类,通过此类,正好可以实现我们的目的。URLClassLoader类的基本使用方法是通过一个URL类型的数组告诉URLClassLoader类的对象是从什么地方加载类,然后使用loadclass()方法,从给定的URL中加载字节码文件,获得它的方法,然后再执行。

 

3.3. 加密重要类
    使用网络加载重要类的方法固然有一定的用处,但是,在遇到无网络的情况时,还是无法解决我们的问题。对于这种情况,我们只能把所有文件放在本地计算机上。那么,对此我们该怎么做才能保护好Java代码呢?
    其实,要实现这一点,并不难,只需要对一些重要的类实行加密就可以了。当然,在装载时,加密的类是需要解密才能被ClassLoader识别的。所以,我们必须自己创建ClassLoader类。在标准Java api中ClassLoader有几个重要的方法。创建定制ClassLoader时,我们只需覆盖其中的一个,即loadClass,添加获取原始类文件数据的代码。这个方法有两个参数:类的名字,以及一个表示JVM是否要求解析类名字的标记(即是否同时装入有依赖关系的类)。如果这个标记为true,我们只需在返回JVM之前调用resolveClass。
    当然,这是需要付出一定的代价的,就是丧失了Java的最大特点--平台无关性。不过,jni技术可以用c语言在多种平台实现,我们可以在不同的平台编写不同的启动程序。

 

3.4. 软件加密锁
    运用外壳工具先把调用用户的Java解释器来进行加密,也就是说如果要运用这个解释器就需要有一把特定的加密锁存在,然后再运用它提供的外壳加密工具中的数据加密,把用户写好的Java程序(Class或JAR包)当作一个文件来处理而对他进行加密,这个加密是采用的锁里自带加密引擎(AES128位)进行加密,加密之后生成新的Java程序。这样用户的软件就只能被用户保护过的Java解释器来进行解释,但是在没有加密锁的情况下就不能够运行用户的软件,从而达到真正保护用户的软件的目的。

 

3.5. 生成exe文件
    利用生成exe文件来防止反编译,有大量免费的工具。

 

3.6. JADE
    由 Sun 中国技术开发中心开发的JADE是一个保护Java产品以防止其被反编译的工具。JADE是能够解决上述问题和能满足用户在这方面需要的第一个工具。它由五部分组成:混淆器、加密器、封装器、类编辑器和输出工具。

 

3.7. 建议
    对于一些需要网络支持的软件来说,可以建立一个Web站点,在站点上存放该软件的关键类,并且建立用户管理机制,用户直接登陆网站进行确认,是许可用户,则发放解密key文件,让其下载关键类,在本地解密运行。这样作的优点是建立的Web站点可以有效的管理密钥以及用户资料。从而起到加强保护软件源代码的作用,并方便软件升级。用C/S结构是不错的选择。或者Java相关得核心用c来做成控件。
    在实际中,也有大量公司出售自己的反编译工具来帮助客户防止商用代码被反编译。

 

4. 深层次一些简单对比

    Java是一种面向对象的编程语言。除了简单的类型,如数字和布尔算子之外,Java中的大部分都是对象。正如任何面向对象的语言一样,Java代码也按类组织。每个类定义一组规定对象行为的方法。一个类可以继承另一个类的行为。在类的根层次上,通常是类对象。
    Java支持单继承类层次结构。这就是说,每个类一次只能继承一个别的类。有些语言允许多继承性,但这可能造成混乱,使语言不必要地复杂化。例如,难以想像,一个对象会继承两个完全不同的类的行为。
    1、自动内存管理:Java对于内存的分配是动态的,并具有垃圾回收机制。
    2、不在类外定义全局变量。
    3、Java中将不再使用goto语句。
    4、Java中取消了指针。
    5、支持固定位数的数据类型。
    6、运行时系统对类型转换进行类型相容性检查。
    7、Java不支持头文件,使用import与其它类通讯。
    8、Java中不包含结构和联合,所有的内容都封装在类中。
    9、Java中不支持宏,它通过final关键字来声明一个常量。
    10、Java不支持多重继承,可以通过Java中的接口实现多重继承的功能。

  评论这张
 
阅读(38)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017