Java程序

2024-07-12

Java程序(精选十篇)

Java程序 篇1

Java语言是一种十分流行的程序开发语言。由SUN公司推出, 具有简易性、健壮性、安全性、可移值性等许多特性。可以用它开发各种应用程序, 是目前主流的开发语言。这里使用Java语言开发一个实用的目录同步程序, 通过实例讲解基本的Java程序开发技术。

2 开发思路

在网络环境中, 往往存在这样的需求。网络中的一台或几台计算机需要和网络中的某一台计算机中的目录文件保持一致。也就要同步的目录名和文件名以及文件内容要完全一样。如果文件发生变化, 变化后的文件将被实时更新。要实现这样的功能, 可以设置有目录同步要求的计算机为服务器, 要进行同步的计算机设置为客户端。双方通过套接字传递数据, 完成同步的功能。

服务器端设置要进行同步的目录名, 然后扫描该目录下的文件, 将要同步的文件名、文件校验码、文件时间、文件大小信息传给客户端;客户端检查要同步的文件, 如发现文件不一致, 就进行文件同步, 如果一致, 就确认同步完成。

3 程序代码

程序中有如下类, 用于搜索目录, 并将搜索到的文件放到一个Array List中:

服务端和客户端按以下规则传递数据, 如表1所示。

使用如下类, 用于读写服务端套接字:

使用如下类, 用于读写客户端套接字:

使用如下类, 用于进行文件校验, 以保证文件可靠传输:

4 结语

程序经过测试, 完成了目录同步的功能, 可以在实际环境中使用。希望本开发实例对从事Java语言开发的读者有所帮助。

参考文献

Java 程序中的多线程Java 篇2

?在Java程序中使用多线程要比在 C 或 C++ 中容易得多,这是因为 Java 编程语言提供了语言级的支持。本文通过简单的编程示例来说明 Java 程序中的多线程是多么直观。读完本文以后,用户应该能够编写简单的多线程程序。

??为什么会排队等待?

??下面的这个简单的 Java 程序完成四项不相关的任务。这样的程序有单个控制线程,控制在这四个任务之间线性地移动。此外,因为所需的资源 ― 打印机、磁盘、数据库和显示屏 -- 由于硬件和软件的限制都有内在的潜伏时间,所以每项任务都包含明显的等待时间。因此,程序在访问数据库之前必须等待打印机完成打印文件的任务,等等。如果您正在等待程序的完成,则这是对计算资源和您的时间的一种拙劣使用。改进此程序的一种方法是使它成为多线程的。

??四项不相关的任务

class myclass {

static public void main(String args[]) {

print_a_file();

manipulate_another_file();

access_database();

draw_picture_on_screen();

}

}

??在本例中,每项任务在开始之前必须等待前一项任务完成,即使所涉及的任务毫不相关也是这样。但是,在现实生活中,我们经常使用多线程模型。我们在处理某些任务的同时也可以让孩子、配偶和父母完成别的任务。例如,我在写信的同时可能打发我的儿子去邮局买邮票。用软件术语来说,这称为多个控制(或执行)线程。

??可以用两种不同的方法来获得多个控制线程:

??☆ 多个进程

??在大多数操作系统中都可以创建多个进程。当一个程序启动时,它可以为即将开始的每项任务创建一个进程,并允许它们同时运行。当一个程序因等待网络访问或用户输入而被阻塞时,另一个程序还可以运行,这样就增加了资源利用率。但是,按照这种方式创建每个进程要付出一定的代价:设置一个进程要占用相当一部分处理器时间和内存资源。而且,大多数操作系统不允许进程访问其他进程的内存空间。因此,进程间的通信很不方便,并且也不会将它自己提供给容易的编程模型。

??☆ 线程

??线程也称为轻型进程 (LWP)。因为线程只能在单个进程的作用域内活动,所以创建线程比创建进程要廉价得多。这样,因为线程允许协作和数据交换,并且在计算资源方面非常廉价,所以线程比进程更可取。线程需要操作系统的支持,因此不是所有的机器都提供线程。Java 编程语言,作为相当新的一种语言,已将线程支持与语言本身合为一体,这样就对线程提供了强健的支持。

??使用 Java 编程语言实现线程

??Java 编程语言使多线程如此简单有效,以致于某些程序员说它实际上是自然的。尽管在 Java 中使用线程比在其他语言中要容易得多,仍然有一些概念需要掌握。要记住的一件重要的事情是 main() 函数也是一个线程,并可用来做有用的工作。程序员只有在需要多个线程时才需要创建新的线程。

??Thread 类

??Thread 类是一个具体的类,即不是抽象类,该类封装了线程的行为。要创建一个线程,程序员必须创建一个从 Thread 类导出的新类。程序员必须覆盖 Thread 的 run() 函数来完成有用的工作。用户并不直接调用此函数;而是必须调用 Thread 的 start() 函数,该函数再调用 run()。下面的代码说明了它的用法:

??创建两个新线程

importjava.util.*;

class TimePrinter extends Thread {

int pauseTime;

String name;

public TimePrinter(int x, String n) {

pauseTime = x;

name = n;

}

public void run() {

while(true) {

try {

System.out.println(name + “:” + new

Date(System.currentTimeMillis()));

Thread.sleep(pauseTime);

} catch(Exception e) {

System.out.println(e);

}

}

}

static public void main(String args[]) {

TimePrinter tp1 = new TimePrinter(1000, “Fast Guy”);

tp1.start();

TimePrinter tp2 = new TimePrinter(3000, “Slow Guy”);

tp2.start();

}

}

??在本例中,我们可以看到一个简单的程序,它按两个不同的时间间隔(1 秒和 3 秒)在屏幕上显示当前时间。这是通过创建两个新线程来完成的,包括 main() 共三个线程。但是,因为有时要作为线程运行的类可能已经是某个类层次的一部分,所以就不能再按这种机制创建线程。虽然在同一个类中可以实现任意数量的接口,但 Java 编程语言只允许一个类有一个父类。同时,某些程序员避免从 Thread 类导出,因为它强加了类层次。对于这种情况,就要 runnable 接口。

??Runnable 接口

??此接口只有一个函数,run(),此函数必须由实现了此接口的类实现。但是,就运行这个类而论,其语义与前一个示例稍有不同。我们可以用 runnable 接口改写前一个示例。(不同的部分用黑体表示。)

??创建两个新线程而不强加类层次

import java.util.*;

class TimePrinterimplements Runnable{

int pauseTime;

String name;

public TimePrinter(int x, String n) {

pauseTime = x;

name = n;

}

public void run() {

while(true) {

try {

System.out.println(name + “:” + new

Date(System.currentTimeMillis()));

Thread.sleep(pauseTime);

} catch(Exception e) {

System.out.println(e);

}

}

}

static public void main(String args[]) {

Thread t1=new Thread(new TimePrinter(1000, “Fast Guy”));

t1.start();

Thread t2=new Thread(new TimePrinter(3000, “Slow Guy”));

t2.start();

}

}

??请注意,当使用 runnable 接口时,您不能直接创建所需类的对象并运行它;必须从 Thread 类的一个实例内部运行它。许多程序员更喜欢 runnable 接口,因为从 Thread 类继承会强加类层次。

??synchronized 关键字

??到目前为止,我们看到的示例都只是以非常简单的方式来利用线程。只有最小的数据流,而且不会出现两个线程访问同一个对象的情况。但是,在大多数有用的程序中,线程之间通常有信息流。试考虑一个金融应用程序,它有一个 Account 对象,如下例中所示:

??一个银行中的多项活动

public class Account {

String holderName;

float amount;

public Account(String name, float amt) {

holderName = name;

amount = amt;

}

public void deposit(float amt) {

amount += amt;

}

public void withdraw(float amt) {

amount -= amt;

}

public float checkBalance() {

return amount;

}

}

??在此代码样例中潜伏着一个错误。如果此类用于单线程应用程序,不会有任何问题。但是,在多线程应用程序的情况中,不同的线程就有可能同时访问同一个 Account 对象,比如说一个联合帐户的所有者在不同的 ATM 上同时进行访问,

在这种情况下,存入和支出就可能以这样的方式发生:一个事务被另一个事务覆盖。这种情况将是灾难性的。但是,Java 编程语言提供了一种简单的机制来防止发生这种覆盖。每个对象在运行时都有一个关联的锁。这个锁可通过为方法添加关键字 synchronized 来获得。这样,修订过的 Account 对象(如下所示)将不会遭受像数据损坏这样的错误:

??对一个银行中的多项活动进行同步处理

public class Account {

String holderName;

float amount;

public Account(String name, float amt) {

holderName = name;

amount = amt;

}

publicsynchronizedvoid deposit(float amt) {

amount += amt;

}

publicsynchronizedvoid withdraw(float amt) {

amount -= amt;

}

public float checkBalance() {

return amount;

}

}

??deposit() 和 withdraw() 函数都需要这个锁来进行操作,所以当一个函数运行时,另一个函数就被阻塞。请注意, checkBalance() 未作更改,它严格是一个读函数。因为 checkBalance() 未作同步处理,所以任何其他方法都不会阻塞它,它也不会阻塞任何其他方法,不管那些方法是否进行了同步处理。

??Java 编程语言中的高级多线程支持

??线程组

??线程是被个别创建的,但可以将它们归类到线程组中,以便于调试和监视。只能在创建线程的同时将它与一个线程组相关联。在使用大量线程的程序中,使用线程组组织线程可能很有帮助。可以将它们看作是计算机上的目录和文件结构。

??线程间发信

??当线程在继续执行前需要等待一个条件时,仅有 synchronized 关键字是不够的。虽然 synchronized 关键字阻止并发更新一个对象,但它没有实现线程间发信。Object 类为此提供了三个函数:wait()、notify() 和 notifyAll()。以全球气候预测程序为例。这些程序通过将地球分为许多单元,在每个循环中,每个单元的计算都是隔离进行的,直到这些值趋于稳定,然后相邻单元之间就会交换一些数据。所以,从本质上讲,在每个循环中各个线程都必须等待所有线程完成各自的任务以后才能进入下一个循环。这个模型称为 屏蔽同步,下例说明了这个模型:

??屏蔽同步

public class BSync {

int totalThreads;

int currentThreads;

public BSync(int x) {

totalThreads = x;

currentThreads = 0;

}

public synchronized void waitForAll() {

currentThreads++;

if(currentThreads < totalThreads) {

try {

wait();

} catch (Exception e) {}

}

else {

currentThreads = 0;

notifyAll();

}

}

}

??当对一个线程调用 wait() 时,该线程就被有效阻塞,只到另一个线程对同一个对象调用 notify() 或 notifyAll() 为止。因此,在前一个示例中,不同的线程在完成它们的工作以后将调用 waitForAll() 函数,最后一个线程将触发 notifyAll() 函数,该函数将释放所有的线程。第三个函数 notify() 只通知一个正在等待的线程,当对每次只能由一个线程使用的资源进行访问限制时,这个函数很有用。但是,不可能预知哪个线程会获得这个通知,因为这取决于 Java 虚拟机 (JVM) 调度算法。

??将 CPU 让给另一个线程

??当线程放弃某个稀有的资源(如数据库连接或网络端口)时,它可能调用 yield() 函数临时降低自己的优先级,以便某个其他线程能够运行。

??守护线程

??有两类线程:用户线程和守护线程。用户线程是那些完成有用工作的线程。 守护线程是那些仅提供辅助功能的线程。Thread 类提供了 setDaemon() 函数。Java 程序将运行到所有用户线程终止,然后它将破坏所有的守护线程。在 Java 虚拟机 (JVM) 中,即使在 main 结束以后,如果另一个用户线程仍在运行,则程序仍然可以继续运行。

??避免不提倡使用的方法

??不提倡使用的方法是为支持向后兼容性而保留的那些方法,它们在以后的版本中可能出现,也可能不出现。Java 多线程支持在版本 1.1 和版本 1.2 中做了重大修订,stop()、suspend() 和 resume() 函数已不提倡使用。这些函数在 JVM 中可能引入微妙的错误。虽然函数名可能听起来很诱人,但请抵制诱惑不要使用它们。

??调试线程化的程序

??在线程化的程序中,可能发生的某些常见而讨厌的情况是死锁、活锁、内存损坏和资源耗尽。

??死锁

??死锁可能是多线程程序最常见的问题。当一个线程需要一个资源而另一个线程持有该资源的锁时,就会发生死锁。这种情况通常很难检测。但是,解决方案却相当好:在所有的线程中按相同的次序获取所有资源锁。例如,如果有四个资源 ―A、B、C 和 D ― 并且一个线程可能要获取四个资源中任何一个资源的锁,则请确保在获取对 B 的锁之前首先获取对 A 的锁,依此类推。如果“线程 1”希望获取对 B 和 C 的锁,而“线程 2”获取了 A、C 和 D 的锁,则这一技术可能导致阻塞,但它永远不会在这四个锁上造成死锁。

??活锁

??当一个线程忙于接受新任务以致它永远没有机会完成任何任务时,就会发生活锁。这个线程最终将超出缓冲区并导致程序崩溃。试想一个秘书需要录入一封信,但她一直在忙于接电话,所以这封信永远不会被录入。

??内存损坏

??如果明智地使用 synchronized 关键字,则完全可以避免内存错误这种气死人的问题。

??资源耗尽

??某些系统资源是有限的,如文件描述符。多线程程序可能耗尽资源,因为每个线程都可能希望有一个这样的资源。如果线程数相当大,或者某个资源的侯选线程数远远超过了可用的资源数,则最好使用 资源池。一个最好的示例是数据库连接池。只要线程需要使用一个数据库连接,它就从池中取出一个,使用以后再将它返回池中。资源池也称为 资源库。

??调试大量的线程

??有时一个程序因为有大量的线程在运行而极难调试。在这种情况下,下面的这个类可能会派上用场:

public class Probe extends Thread {

public Probe() {}

public void run() {

while(true) {

Thread[] x = new Thread[100];

Thread.enumerate(x);

for(int i=0; i<100; i++) {

Thread t = x[i];

if(t == null)

break;

else

System.out.println(t.getName() + “ ” + t.getPriority()

+ “ ” + t.isAlive() + “ ” + t.isDaemon());

}

}

}

}

??限制线程优先级和调度

??Java 线程模型涉及可以动态更改的线程优先级。本质上,线程的优先级是从 1 到 10 之间的一个数字,数字越大表明任务越紧急。JVM 标准首先调用优先级较高的线程,然后才调用优先级较低的线程。但是,该标准对具有相同优先级的线程的处理是随机的。如何处理这些线程取决于基层的操作系统策略。在某些情况下,优先级相同的线程分时运行;在另一些情况下,线程将一直运行到结束。请记住,Java 支持 10 个优先级,基层操作系统支持的优先级可能要少得多,这样会造成一些混乱。因此,只能将优先级作为一种很粗略的工具使用。最后的控制可以通过明智地使用 yield() 函数来完成。通常情况下,请不要依靠线程优先级来控制线程的状态。

??小结

??本文说明了在 Java 程序中如何使用线程。像是否应该使用线程这样的更重要的问题在很大程序上取决于手头的应用程序。决定是否在应用程序中使用多线程的一种方法是,估计可以并行运行的代码量。并记住以下几点:

??☆ 使用多线程不会增加 CPU 的能力。但是如果使用 JVM 的本地线程实现,则不同的线程可以在不同的处理器上同时运行(在多 CPU 的机器中),从而使多 CPU 机器得到充分利用。

??☆ 如果应用程序是计算密集型的,并受 CPU 功能的制约,则只有多 CPU 机器能够从更多的线程中受益。

??☆ 当应用程序必须等待缓慢的资源(如网络连接或数据库连接)时,或者当应用程序是非交互式的时,多线程通常是有利的。

??☆ 基于 Internet 的软件有必要是多线程的;否则,用户将感觉应用程序反映迟钝。例如,当开发要支持大量客户机的服务器时,多线程可以使编程较为容易。在这种情况下,每个线程可以为不同的客户或客户组服务,从而缩短了响应时间。

??某些程序员可能在 C 和其他语言中使用过线程,在那些语言中对线程没有语言支持。这些程序员可能通常都被搞得对线程失去了信心。

浅谈Java桌面应用程序开发 篇3

【摘 要】Java对于服务器,个人电脑和移动设备来说是一项伟大的技术。由于需要java的跨平台的特性,因此java在服务器和移动设备方面的应用是非常成功的。Java开发的桌面程序既有友好易用的图形用户界面,也能够实现相应的功能。【关键词】桌面开发

AWT

Swing SWT Java与桌面端现在流行的桌面平台要数Windows、Mac和 Linux。但它们不是十全十美的,Windows主宰着桌面操作系统的市场,其上有巨大的应用和开发群体,但它昂贵且有许多安全漏洞。Linux有着稳固的基础,它是开源的软件,比Windows更可靠。Mac非常容易操作且不是黑客的目标,但与Windows和Linux比起来,Mac的硬件和软件可选的余地非常的有限。Windows、Linux和Mac 在桌面的流行创造了多样性,这种多样性正是Java需要的,这就使得Java在桌面有举足轻重的地位。跨平台的支持Java 运行于所有相关的操作系统,包括Windows、Mac和Linux。也就是说把现有的应用从一个操作系统移植到另一个操作系统而不用做太多的改动,所以Java是首选的桌面开发平台。或许用微软的可视化工具很容易构建.NET应用,但是这将使软件被绑定在了Windows平台上。也许有人想用Linux 代替Windows 从而避免由微软操作系统的漏洞带来的问题,但是用户不能容忍的问题之一是当从Windows移植到Linux时所带来的巨大的费用。如果应用程序用Java构建,就没有了这些问题,Java的图形用户界面看上去会跟使用的操作系统一样,而并不需要做什么改动。丰富的特征最初,Java只有非常有限的一些特征去构建图形用户界面,思想就是用与平台无关的Java应用程序接口打包不同的操作系统的本地图形用户界面,称之为抽象的窗口工具。它仅有普通的部件如文件域、文本区、选择框、单选按钮、列表框和按钮被AWT支持,图形和图像的特性支持非常有限,也就是说,只能够构建简单的applet程序。认识到需要更高级的图形用户界面组件和图形能力,Sun公司开发了Swing,Java 2D,Java 3D,图像的输入/输出,Java高级图像(JAI)和很多其它的组件。这些中的一些窗体组件现在已经是Java 2标准版(J2SE)里的一部分。例如Swing、Java 2D、图像的输入/输出都是Java的核心API,它们随着Java开发工具包(JDK)和Java运行环境一起被提供给用户。Java图形界面工具Java有三个主要的图形界面工具:AWT,Swing和SWT。Swing 是构建java图形界面标准的API(应用程序接口),一些AWT类由Swing继承而来。SWT是一个非常有前途的新的窗体工具,由IBM资助。但是事实上,这三者相互补充,它们满足不同的需求。AWT抽象窗口工具包(Abstract Windowing Toolkit)(AWT)是Java的平台独立的窗口系统,图形和用户界面器件工具包。AWT是Java基础类(JFC)的一部分,为Java程序提供图形用户界面(GUI)的标准API。AWT提供了JavaApplet和Java Application中可用的用户图形界面GUI中的基本组件(components)。由于Java是一种独立于平台的程序设计语言,但GUI却往往是依赖于特定平台的,Java采用了相应的技术使得AWT能提供给应用程序独立于机器平台的接口,这保证了同一程序的GUI在不同机器上运行具有类似的外观(不一定完全一致)。SwingSwing是一个用于开发Java应用程序用户界面的开发工具包。它以抽象窗口工具包(AWT)为基础使跨平台应用程序可以使用任何可插拔的外观风格。Swing开发人员只用很少的代码就可以利用Swing丰富、灵活的功能和模块化组件来创建优雅的用户界面。工具包中所有的包都是以swing作为名称。SWTSWT是IBM为它的Eclipse集成开发环境而开发的图形用户界面工具。SWT可以在Eclipse环境外使用,而且提供对操作系统本地图形用户界面的直接访问。因此,基于SWT的Java应用程序拥有本地的图形用户界面并且可以和本地别的应用程序和部件集成在一起。SWT社区现在正在设计浏览器API,这些API可以产生基于IE或者Mozilla的HTML窗口。SWT现在可以在AIX,HPUX,Linux,QNX,Solaris,和Windows下面运行。误解与Bug对于java/Swing一直有着误解,诸如:Java/Swing太慢了,或者是Java/Swing需要更多的内存。也许老式的奔腾运行JDK1。2确实很慢,但是PIII级别的CPU运行JDK1。4环境是足够快的。一个应用程序中鼠标在1毫秒和在10毫秒的反映的差异,从使用者方面来说是没什么区别的。Java不但在企业级的上千人同时在线的服务器中表现良好,而且在仅有有限资源的移动设备上的表现也是很出色的。总结Java作为一种网络技术,是为了在浏览器中能够运行小应用程序而发布,但是它从开始就有运行独立的桌面应用程序的能力。不幸的是,AWT没有提供足够的桌面端的程序所需的特性。Swing着手于解决这些问题,但是它有不少的bug。今天,Java有构建大型桌面端应用程序的能力并修复了bug。Java独有的优点是“只写一次,到处运行”——在Windows,Linux,Mac和其它操作系统上运行Java代码的能力。【参考文献】[1]Eric,Java编程思想[M],第4版,机械工业出版社,2007年4月[2]Metsker S J,Java设计模式[M],第2版,电子工业出版社,2012年09 月[3]毕建信,基于MVC设计模式的Web应用研究与实现[D],武汉理工大学出版社,2006年5月

UDP的Java聊天程序 篇4

Java语言似乎专门为网络设计的,用其开发网络软件特别便利,在Internet时代,Java热遍及全球,学习和使用Java的人越来越多。在Java中进行网络编程是相对容易的,因为J2SE中的java.net包已经对各种通信协议很好地进行了封装。文中用Java来实现基于UDP的聊天程序,限于篇幅,只实现了基本的聊天功能。

首先,要介绍Java中封装UDP编程的类———DatagramSocket,这是用来发送和接收数据报的套接字。在程序启动后,可以在构造函数中提供端口参数用以在本地主机上绑定一个端口,以便接收和发送数据报。DatagramSocket类的send方法可以将参数对象的数据报发送到目的主机的目的端口;receive方法可以接收网络上其他主机发送过来的数据报并封装成对象。

其次,要介绍的就是承载数据报的对象DatagramPacket,这个对象封装了UDP的数据报数据,通过重载构造函数,提供不同的参数,可以把DatagramPacket构造成发送数据或接收数据的数据报对象。发送数据的对象将作为DatagramSocket类的send方法的参数;接收数据的对象将作为DatagramSocket类的receive方法的参数。

以上两个类,其实就基本可以实现UDP方式的网络聊天功能了,但是为了数据报能够正确发送,还得借助InetAddress类。InetAddress类表示互联网协议(IP)地址,通过调用静态方法getByName并提供字符串形式的IP地址参数就可以得到对应的IP地址对象,把它传给DatagramPacket,再用UDP套接字的send方法就可以向IP地址对应的主机发送数据了。

为了方便用户的使用,把程序分成两个类,主类为Chat,里面有主函数main,以便应用程序的运行;另一个类FrameMain,扩展了窗体类,方便用户输入及显示消息。主函数main中实例化了主窗体FrameMain。

接下来来看具体代码,为描述程序的方便,分块地来研究,先看代码片断1:

以上对象都是程序中要使用的主要对象,除了本地监听端口设了9000的值,其他对象都是空对象。recvPacket对象将在套接字调用完receive方法后实例化,而sendPacket对象和IP对象将在触发发送数据报的代码时创建。UDPSocket对象是核心,将在一个单独的初始化方法jbInit(JBuilder开发工具默认生成的方法)中对这个对象进行创建,并且在窗体构造函数中调用jbInit方法。请看以下jbInit方法的代码片断2:

以上代码在实例化UDPSocket对象时以9000的端口号作为监听端口。UDP套接字通过调用receive方法监听数据报并实例化recvPacket,但是由于该方法在接收到数据报前一直阻塞,所以为了与主界面功能互不影响,将这个会阻塞的方法放到一个单独的线程中,这样,主界面的发送和显示功能与接收数据报的功能可以认为是同时在进行,互不干扰。请看以下代码片断3:

以上代码中,run函数定义在主界面类FrameMain中,它实现了Runnable接口,然后在jbInit函数中创建了一个子线程recvThread,将主界面的实例传给子线程,意味着子线程在运行过程中要工作的代码写在主界面的run函数中,并且调用start方法启动子线程(参见代码片断2)。UDPSocket对象的receive方法返回后,recvPacket中就有了数据报的内容,通过调用getData方法获取字节数组,并组合成字符串显示。那么,recvPacket中的数据是谁发来的呢?答案就是网络中的其他主机,发送数据报的过程是,先得到用户的输入数据,然后得到用户输入的目标主机和端口,最后组合成数据报对象sendPacket,调用UDP套接字的send方法发送。请看以下代码片断4:

以上代码中,jtfSend是用户输入聊天信息的文本框,jtaReceive是显示接收信息的多行文本框。sendMessage函数可以由输入框(jtfSend对象)或发送按钮的Action事件调用,信息朝目标主机同端口(9000号端口,sendPacket构造函数的第四个参数)发送后,同时也显示在本机聊天窗体的信息框中。为了测试程序,我们用两台局域网内的主机做实验,A主机IP地址为172.16.10.166,B主机IP地址为172.16.10.222。分别在两台主机中运行聊天程序,并相互输入聊天信息,可见程序运行结果如图1所示。

由此可见,用Java语言实现简单的UDP聊天程序是相当容易的,核心的收发数据报功能只要借助DatagramSocket和DatagramPacket两个类就可以完成,如果再把其他功能完善一下,就可以编写出更有实际用途的网络聊天程序。

摘要:UDP是OSI参考模型中一种无连接的传输层协议,它提供了简单不可靠的信息传送服务。由于UDP比较简单,UDP头包含很少的字节,所以它在速度方面有很大优势。很多常用的即时通软件,如QQ程序,都会使用UDP实现很多基本功能。Java语言是当今流行的网络编程语言,它的API封装了UDP编程的类,用来实现UDP聊天程序很容易。

关键词:UDP,Java,聊天程序

参考文献

[1]UDP.用户数据报协议.http://www.networkdictionary.cn/pro-tocols/udp.php.

[2]方建文.Java UDP编程及应用.电脑学习,2005,1.

Java程序 篇5

1.abstract class Name { private String name;public abstract boolean isStupidName(String name){} }大侠们,这有何错误?答案: 错。abstract method必须以分号结尾,且不带花括号。

2.public class Something { void doSomething(){ private String s = “";int l = s.length();} }有错吗? 答案: 错。局部变量前不能放置任何访问修饰符(private,public,和protected)。final可以用来修饰局部变量(final如同abstract和strictfp,都是非访问修饰符,strictfp只能修饰class和method而非variable)。

3.abstract class Something { private abstract String doSomething();}这好像没什么错吧? 答案: 错。abstract的methods不能以private修饰。abstract的methods就是让子类implement(实现)具体细节的,怎么可以用private把abstract method封锁起来呢?(同理,abstract method前不能加final)。

4.public class Something { public int addOne(final int x){ return ++x;} }这个比较明显。

答案: 错。int x被修饰成final,意味着x不能在addOne method中被修改。

5.public class Something {

public static void main(String[] args){ Other o = new Other();new Something().addOne(o);}

public void addOne(final Other o){ o.i++;} } class Other { public int i;}和上面的很相似,都是关于final的问题,这有错吗? 答案: 正确。在addOne method中,参数o被修饰成final。如果在addOne method里我们修改了o的reference,(比如: o = new Other();),那么如同上例这题也是错的。但这里修改的是o的member vairable(成员变量),而o的reference并没有改变。

6.class Something { int i;

public void doSomething(){ System.out.println(”i = “ + i);} } 有什么错呢? 看不出来啊。

答案: 正确。输出的是”i = 0“。int i属於instant variable(实例变量,或叫成员变量)。instant variable有default value。int的default value是0。

7.class Something { final int i;

public void doSomething(){ System.out.println(”i = “ + i);} }和上面一题只有一个地方不同,就是多了一个final。这难道就错了吗? 答案: 错。final int i是个final的instant variable(实例变量,或叫成员变量)。final的instant variable没有default value,必须在constructor(构造器)结束之前被赋予一个明确的值。可以修改为”final int i = 0;“。

8.public class Something {

public static void main(String[] args){ Something s = new Something();

System.out.println(”s.doSomething()returns “ + doSomething());}

public String doSomething(){ return ”Do something...“;} } 看上去很完美。

答案: 错。看上去在main里call doSomething没有什么问题,毕竟两个methods都在同一个class里。但仔细看,main是static的。static method不能直接call non-static methods。可改成”System.out.println(“s.doSomething()

returns

+ s.doSomething());“。同理,static method不能访问non-static instant variable。

9.此处,Something类的文件名叫 OtherThing.javaclass Something {

private static void main(String[] something_to_do){ System.out.println(”Do something...“);} } 这个好像很明显。

答案: 正确。从来没有人说过Java的Class名字必须和其文件名相同。但public class的名字必须和文件名相同。

10.interface A{

int x = 0;} class B{ int x =1;}

class C extends B implements A { public void pX(){ System.out.println(x);}

public static void main(String[] args){ new C().pX();} } 答案:错误。在编译时会发生错误(错误描述不同的JVM有不同的信息,意思就是未明确的x调用,两个x都匹配(就象在同时import java.util和java.sql两个包时直接声明Date一样)。对于父类的变量,可以用super.x来明确,而接口的属性默认隐含为 public static final.所以可以通过A.x来明确。

11.interface Playable {

void play();} interface Bounceable { void play();}

interface Rollable extends Playable, Bounceable { Ball ball = new Ball(”PingPang“);}

class Ball implements Rollable { private String name;public String getName(){ return name;}

public Ball(String name){ this.name = name;}

public void play(){

ball = new Ball(”Football“);System.out.println(ball.getName());} }这个错误不容易发现。

答案: 错。”interface Rollable extends Playable, Bounceable“没有问题。interface可继承多个interfaces,所以这里没错。问题出在interface Rollable里的”Ball ball = new Ball(“PingPang”);“。任何在interface里声明的interface variable(接口变量,也可称成员变量),默认为public static final。也就是说”Ball ball = new Ball(“PingPang”);“实际上是”public static final Ball ball = new Ball(“PingPang”);“。在Ball类的Play()方法中,”ball = new Ball(“Football”);“改变了ball的reference,而这里的ball来自Rollable interface,Rollable interface里的ball是public static final的,final的object是不能被改变reference的。因此编译器将在”ball = new Ball(“Football”);“这里显示有错。

JAVA编程题 1.现在输入n个数字,以逗号,分开;然后可选择升或者降序排序;按提交键就在另一页面显示按什么排序,结果为,提供reset import java.util.*;public class bycomma{

public static String[] splitStringByComma(String source){ if(source==null||source.trim().equals(”“))

return null;

StringTokenizer commaToker=new tringTokenizer(source,”,“);String[] result = new String[commaToker.countTokens()];int i=0;

while(commaToker.hasMoreTokens()){ result[i] = commaToker.nextToken();i++;} return result;} public static void main(String args[]){

String[] s = splitStringByComma(”5,8,7,4,3,9,1“);int[] ii = new int[s.length];for(int i = 0;i

for(int i=(s.length-1);i>=0;i--){ System.out.println(ii[i]);} } }

2.金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。package test.format;import java.text.NumberFormat;import java.util.HashMap;public class SimpleMoneyFormat { public static final String EMPTY = ”“;public static final String ZERO = ”零“;public static final String ONE = ”壹“;public static final String TWO = ”贰“;public static final String THREE = ”叁“;public static final String FOUR = ”肆“;public static final String FIVE = ”伍“;public static final String SIX = ”陆“;public static final String SEVEN = ”柒“;public static final String EIGHT = ”捌“;public static final String NINE = ”玖“;public static final String TEN = ”拾“;public static final String HUNDRED = ”佰“;public static final String THOUSAND = ”仟“;public static final String TEN_THOUSAND = ”万“;public static final String HUNDRED_MILLION = ”亿“;public static final String YUAN = ”元“;public static final String JIAO = ”角“;public static final String FEN = ”分“;public static final String DOT = ”.“;

private static SimpleMoneyFormat formatter = null;private HashMap chineseNumberMap = new HashMap();private HashMap chineseMoneyPattern = new HashMap();private

NumberFormat

numberFormat NumberFormat.getInstance();private SimpleMoneyFormat(){

numberFormat.setMaximumFractionDigits(4);numberFormat.setMinimumFractionDigits(2);

= numberFormat.setGroupingUsed(false);chineseNumberMap.put(”0“, ZERO);chineseNumberMap.put(”1“,ONE);chineseNumberMap.put(”2“, TWO);chineseNumberMap.put(”3“, THREE);chineseNumberMap.put(”4“, FOUR);chineseNumberMap.put(”5“, FIVE);chineseNumberMap.put(”6“, SIX);chineseNumberMap.put(”7“, SEVEN);chineseNumberMap.put(”8“, EIGHT);chineseNumberMap.put(”9“, NINE);chineseNumberMap.put(DOT, DOT);chineseMoneyPattern.put(”1“, TEN);chineseMoneyPattern.put(”2“, HUNDRED);chineseMoneyPattern.put(”3“, THOUSAND);chineseMoneyPattern.put(”4“, TEN_THOUSAND);chineseMoneyPattern.put(”5“, TEN);chineseMoneyPattern.put(”6“, HUNDRED);chineseMoneyPattern.put(”7“, THOUSAND);chineseMoneyPattern.put(”8“, HUNDRED_MILLION);} public static SimpleMoneyFormat getInstance(){ if(formatter == null)

formatter = new SimpleMoneyFormat();return formatter;} public String format(String moneyStr){

checkPrecision(moneyStr);String result;

result = convertToChineseNumber(moneyStr);result = addUnitsToChineseMoneyString(result);

return result;}

public String format(double moneyDouble){

return format(numberFormat.format(moneyDouble));}

public String format(int moneyInt){

return format(numberFormat.format(moneyInt));}

public String format(long moneyLong){

return format(numberFormat.format(moneyLong));} public String format(Number moneyNum){

return format(numberFormat.format(moneyNum));

private String convertToChineseNumber(String moneyStr){ String result;

StringBuffer cMoneyStringBuffer = new StringBuffer();for(int i = 0;i < moneyStr.length();i++){

cMoneyStringBuffer.append(chineseNumberMap.get(moneyStr.substring(i, i + 1)));

//拾佰仟万亿等都是汉字里面才有的单位,加上它们

int indexOfDot = cMoneyStringBuffer.indexOf(DOT);int moneyPatternCursor = 1;for(int i = indexOfDot1)

cMoneyStringBuffer.delete(cMoneyStringBuffer.length()1, JIAO);

cMoneyStringBuffer.insert(cMoneyStringBuffer.length(), FEN);if(cMoneyStringBuffer.indexOf(”零角零分“)!=-1)//没有零头,加整 cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf(”零角零分“), cMoneyStringBuffer.length(), ”整“);

else if(cMoneyStringBuffer.indexOf(”零分“)!=-1)//没有零分,加

cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf(”零分“), cMoneyStringBuffer.length(), ”整“);else { if(cMoneyStringBuffer.indexOf(”零角“)!=-1)

cMoneyStringBuffer.delete(cMoneyStringBuffer.indexOf(”零角“),cMoneyStringBuffer.indexOf(”零角“)+2);

tmpBuffer.append(”整“);

} result = cMoneyStringBuffer.toString();return result;} private void checkPrecision(String moneyStr){ int

fractionDigits

=

moneyStr.length()

-moneyStr.indexOf(DOT)-1;

if(fractionDigits > 2)throw new RuntimeException(”金额“ + moneyStr + ”的小数位多于两位。“);//精度不能比分低

} public static void main(String args[]){ System.out.println(getInstance().format(new Double(10010001.01)));} }

3、继承时候类的执行顺序问题,一般都是选择题,问你将会打印出什么? 答:父类:

package test;

public class FatherClass { public FatherClass(){

System.out.println(”FatherClass Create“);} } 子类: package test;

import test.FatherClass;

public class ChildClass extends FatherClass { public ChildClass(){

System.out.println(”ChildClass Create“);}

public static void main(String[] args){ FatherClass fc = new FatherClass();ChildClass cc = new ChildClass();} }

输出结果: C:>java test.ChildClass FatherClass FatherClass Create

ChildClass Create

4、内部类的实现方式? 答:示例代码如下:

package test;

public class OuterClass { private class InterClass { public InterClass(){

System.out.println(”InterClass Create“);} }

public OuterClass(){

InterClass ic = new InterClass();System.out.println(”OuterClass Create“);}

public static void main(String[] args){ OuterClass oc = new OuterClass();}

Create }

输出结果: C:>java test/OuterClass InterClass Create

OuterClass Create 再一个例题:

public class OuterClass { private double d1 = 1.0;//insert code here }

You need to insert an inner class declaration at line 3.Which two inner class declarations are valid?(Choose two.)

A.class InnerOne{ public static double methoda(){return d1;} } B.public class InnerOne{ static double methoda(){return d1;} } C.private class InnerOne{ double methoda(){return d1;} } D.static class InnerOne{ protected double methoda(){return d1;} } E.abstract class InnerOne{ public abstract double methoda();} 说明如下: 一.静态内部类可以有静态成员,而非静态内部类则不能有静态成员。故 A、B 错 二.静态内部类的非静态成员可以访问外部类的静态变量,而不可访问外部类的非静态变量;return d1 出错。故 D 错 三.非静态内部类的非静态成员可以访问外部类的非静态变量。故 C 正确 四.答案为C、E

5、Java 的通信编程,编程题(或问答),用JAVA SOCKET编程,读服务器几个字符,再写入本地显示?

答:Server端程序: package test;import java.net.*;import java.io.*;public class Server { private ServerSocket ss;private Socket socket;private BufferedReader in;private PrintWriter out;public Server(){ try {

ss=new ServerSocket(10000);while(true){

socket = ss.accept();String

RemoteIP

= socket.getInetAddress().getHostAddress();String RemotePort = ”:“+socket.getLocalPort();System.out.println(”A in!IP:“+RemoteIP+RemotePort);in

=

new

BufferedReader(new client

come InputStreamReader(socket.getInputStream()));String line = in.readLine();

System.out.println(”Cleint send is :“ + line);out

=

new PrintWriter(socket.getOutputStream(),true);out.println(”Your Message Received!“);out.close();in.close();socket.close();}

}catch(IOException e){ out.println(”wrong“);} }

public static void main(String[] args){ new Server();} }

Client端程序: package test;import java.io.*;import java.net.*;public class Client { Socket socket;BufferedReader in;PrintWriter out;public Client(){ try {

System.out.println(”Try to Connect to 127.0.0.1:10000“);socket = new Socket(”127.0.0.1“,10000);System.out.println(”The Server Connected!“);System.out.println(”Please enter some Character:");BufferedReader

line

=

new

BufferedReader(new InputStreamReader(System.in));

out = new PrintWriter(socket.getOutputStream(),true);Out

3、接口和内部类、抽象类的特征答:接口:在一个类里,只有申明没有实现。内部类:是在一个类的内部定义的一个类;抽象类:是以abstract 定义的,里面至少有一个抽象方法。

4、文件读写的基本类

答:File Reader 类和FileWriter类分别继承自Reader类和Writer类。FileReader类用于读取文件,File Writer类用于将数据写入文件,这两各类在使用前,都必须要调用其构造方法创建相应的对象,然后调用相应的read()或 write()方法。

6、线程的基本概念、线程的本状态以及状态之间的关系 ?新建(Born): 新建的线程处于新建状态?就绪(Ready): 在创建线程后,它将处于就绪状态,等待 start()方法被调用?运行(Running): 线程在开始执行时进入运行状态?睡眠(Sleeping): 线程的执行可通过使用 sleep()方法来暂时中止。在睡眠后,线程将进入就绪状态?等待(Waiting): 如果调用了 wait()方法,线程将处于等待状态。用于在两个或多个线程并发运行时。?挂起(Suspended): 在临时停止或中断线程的执行时,线程就处于挂起状态。?恢复(Resume): 在挂起的线程被恢复执行时,可以说它已被恢复。?阻塞(Blocked)– 在线程等待一个事件时(例如输入/输出操作),就称其处于阻塞状态。?死亡(Dead)– 在 run()方法已完成执行或其 stop()方法被调用之后,线程就处于死亡状态。

5、串行化的注意事项以及如何实现串行化答:如果有循环引用是不可以串行化的。对象输出流的WriteObject方法和 对象输入流的ReadObect 方法

7、线程的同步、如何实现线程的同步答:当两个或多个线程同时访问同一个变量,并且以个线程需要修改这个变量。就要用到线程同步。在Java 中,同步是通过 synchronized 关键字来定义的。诺是想同步化某程序段,可以使用 synchronized(object){}方法,其中{}内的程序语句被同步化。

9、socket通信(tcp/udp区别及JAVA的实现方式)TCP——传输控制协议,具有极高的可靠性,保证数据包按照顺序准确到达,但其也有着很高的额外负担。UDP——使用者数据元协议,并不能保证数据包会被成功的送达,也不保证数据包到达的顺序,但其传输速度很快。大多数我们会使用TCP,偶尔才会动用UDP,如声音讯号,即使少量遗失,也无

关紧要。

10、JAVA的事件委托机制和垃圾回收机制

java 事件委托机制的概念,一个源产生一个事件并将它送到一个或多个监听器那里。在这种方案中,监听器简单的等待,直到它收到一个事件。一旦事件被接受,监听器将处理这个事件,然后返回。垃圾回收机制 垃圾收集是将分配给对象但不在使用的内存回收或释放的过程。如果一个对象没有指向它的引用或者其赋值为null,则次对象适合进行垃圾回收

11、JDBC调用数据库的基本步骤导入必要的类,装入JDBC驱动程序,识别数据源,分配一个Connection对象,分配一个Statement对象,使用Statement执行一个查询,从返回的ResultSet对象中检索数据,关闭ResultSet,关闭Statement对象,关闭Connection对象

12、解析XML文件的几种方式和区别答:Dom解析 在内存中创建一个DOM树,能随机访问文件内容,也可以修改原文件内容SAX解析 线性解析,不能随机访问,也无法修改原文件Dom解析要先用SAX解析创建DOM树

13、JAVA的四种基本权限的定义public private protected 默认

Java程序 篇6

关键词:程序设计 能力目标 项目教学 教学方案

计算机软件技术专业主要培养具有创新精神和良好的职业道德的软件专业高级专门人才。本专业毕业生主要面向企、事业单位的管理部门和计算机软件开发部门,从事项目负责人、软件程序员、软件测试员、数据库设计师、系统管理员等工作。目前在程序设计应用领域,面向对象的JAVA语言编程和相关的JAVA技术应用相当广泛,JAVA语言成为主流的程序设计开发语言之一,计算机软件技术专业开设的《JAVA程序设计》课程就是要让学生掌握这种主流的程序设计工具,并且能够根据工作平台的实际要求,设计应用软件,解决实际应用中的一些问题。

为了达到更好的教学效果,我们需要构建理论与实践一体化的教学模式,确立重应用能力培养的课程体系,将技能训練贯穿于整个教学环节中,以企业用人标准为培养目标来进行人才的培养工作。

《JAVA程序设计》课程的能力培养目标列举如下:

1、掌握JDK的安装配置,能够熟练地在计算机上安装配置JAVA的运行环境。

2、写符合JAVA语言语法规范的程序代码。

3、养成查阅JAVA官方文档的习惯,能够在帮助文档中获取系统定义类的属性、方法等信息,熟练掌握JDK帮助文档的正确查阅和使用方法。

4、建立面向对象的程序设计思想,学会类的基本设计;能够用面向对象的观点分析、构建实际应用中的对象。

5、学会使用继承的方法设计新的类。

6、理解多态的含义,掌握多态的表现手段,能够根据应用的需要使用多态技术。

7、给应用程序设计构建美观、实用的图形用户界面。

8、在程序设计中能够分析可能发生的异常,并在程序中处理异常。

9、能够用JAVA中提供的流方式对文件进行操作。

10、学会进行数据库的连接,能够通过程序操作数据库,如查询、增、删、改等,从而实现对数据库中各种数据的处理。

11、理解网络通讯协议的概念及作用,熟悉JAVA中利用TCP/IP协议进行网络通讯的机制,能够用JAVA语言编写网络应用程序。

12、利用线程机制设计多用户应用程序。

13、学会利用工具将应用程序生成可执行文件,并在应用环境中发布。

14、对中、小型应用系统的开发流程有一个清楚的认识和经历。

围绕本课程确定的培养目标,在教学中以项目教学方法为主。“项目教学法”是通过实施完整的项目来进行的教学活动,其目的就是要在课堂教学中把理论与实践教学有机地结合起来,充分发掘学生的创造潜能,训练学生小组协作和团队精神,让学生在应用中学习,在实践需要时学习,从而提高学生解决实际问题的综合能力。“项目教学法”是近几年在职业教育领域比较提倡的方法,但在应用中还是应该注意一些问题,比如:项目的选择应具有目的性,所选项目应包含教学计划内要教的各学科的内容;项目应具有完整性,项目从设计、实施到完成必须要能够有一个完整的成品出来,作为项目的成果;在教学中教师要充分的准备工作;要调动学生参与项目的积极性,项目教学的实施要精心地组织安排;对项目结果进行检查,做合理公平的评价等。

在对项目教学法本质及注意问题进行充分认识和分析的情况下,综合考虑各方面因素,结合学生的实际,设计了《JAVA程序设计》课程教学组织的初步实施方案:

把《JAVA程序设计》课程中涉及到的知识划分为五个项目模块:

一、经典C++程序转换模块

这部分的安排主要是借复习C++的语法知识,来快速熟悉JAVA语言的基本语法、流程控制语句等内容,并在从C++语言向JAVA语言的转换过程中,把JAVA的不同之处突出表现,将其作为重点训练。传统的教学过程中,总是将JAVA语言的语法讲解一遍,虽然是不同的语言,但存在太多相同的东西,重复的讲解容易让学生一开始就厌倦课程,这样的调整一方面避免了重复;另一方面还可以节省教学课时,为后期学生实际动手操作训练提供更充足的时间。这一部分可以把传统教材上关于JAVA语言入门、运算符表达式和流程控制、数组和方法、面向对象的程序设计等章节的知识涵盖在其中。

二、界面设计模块

考虑到项目的功能都是在一个美观、实用的前台界面之上实现的,所以第二个模块安排进行应用程序界面设计训练。JAVA中提供进行界面设计主要是AWT、SWING两个包,对于这部分工作涉及到的支撑知识,主要是各种图形界面控件类的使用。第三、第四、第五模块中涉及到的三个应用软件,都具有图形用户界面,将三个小软件的界面作为此阶段的教学案例。安排教师讲解演示一个项目界面,学生课下同步仿制一个项目界面,熟练独立设计一个项目界面的思路完成教学。这一部分涵盖了传统教材上JAVA图形用户界面、JAVA类库和常用类简介等章节知识。

三、俄罗斯方块游戏项目模块

本项目是一个小游戏,容易激发学生的学习兴趣,同时又是一般学生都玩过、都比较熟悉的,同时完成之后,学生也比较容易找到成就感。教师分析项目功能需求,逐步引导学生思考,并分析演示实现方法。第三模块阶段以教师为主,教师演示,学生模仿操作。这部分任务的完成要靠第一、二模块准备的JAVA基础,主要用到数组字符串、事件处理、异常处理等章节知识。

四、网络文件传输项目模块

进入第四模块,项目的完成主要靠学生,教师在其中主要起引导作用。首先引导学生按照软件工程的方法对软件的开发进行需要分析,确定完成的功能,明确实现过程,画出处理流程图;利用前期掌握的知识,根据确定的软件功能完成界面的调整修改;设计单机中文件及文件夹的建立、复制、删除功能;加入网络连接操作,实现网络中文件的传输。本模块主要训练对文件的操作和网络连接的建立。

五、QQ聊天软件项目模块

此模块是对学生进行JAVA项目开发强化训练的部分,使用到前期涉及到的所有知识。由学生独立根据自己的经验进行项目分析,严格按照软件工程的要求进行;根据个人爱好设计有个性的聊天界面;独立架构聊天软件的网络通讯框架;添加多用户同时在线聊天功能;将聊天用户的用户名、密码及相关信息采用数据库管理,登录时进行身份验证。此环节重点训练多线程和数据库连接、操作等章节知识。

以上的五个模块设计层层递进,并在递进中有重叠,有承上启下的目的,巩固上一环节,服务下一模块。任何的一个新的方案都需要在实践中进行检验,通过实践我们可以不断地进行改进和调整,把教学中使用的项目设计更好更全面,从而达到最优的教学效果。

参考文献:

[1] 姜大源. 职业教育学研究新论.教育科学出版社.2007.1

[2] 冯向东.学科、专业建设与人才培养.高等教育研究.2002.3

[3] 孙伟. 《Java程序设计》课程的教学改革与实践. 计算机时代. 2005.11

Java程序的安全机制研究 篇7

关键词:Java程序,安全机制,安全管理器

Java语言是一种基于类型安全的强类型语言, 利用Java语法与Java语义来规定Java类型, 并保证Java程序的安全性。随着计算机技术的不断发展, Java程序安全性不断完善, 其安全机制包括“认证”、“权限控制”、“加密、解密与签名”、“安全套接字连接”等。但是从应用实际现状来看, 任何程序的应用安全都是相对的, 想要在现有基础上更进一步提高Java程序安全性, 就需要对其安全机制进行深入研究。

1 Java运行方式分析

Java程序主要采取先编译、后解释以及执行的运行方式, 其程序代码并不在本地操作系统层上运行, 且不能直接调用本地操作系统方法与工程, 而是需要通过JVM调度与审核来完成一切运行。JVM作为Java程序运行的虚拟平台, 应用此种运行方式, 一方面可以保证Java程序平台无关性, 另一方面同时也可以为Java程序安全性提供审核空间, 以及相应安全检测策略, 避免网络环境中存在恶意程序对计算机程序进行攻击与破坏, 提高程序运行安全性。

2 Java安全特性分析

2.1 类型安全

Java程序运行时想要保证自身安全性, 首先需要保证类型系统的安全性。对类型安全进行分析, 需要从两个方面进行, 即类型检查与类型安全。一般情况下, 计算机整体结构中, 任何区域均存有必要的Java对象, 并且每个对象均具有自身对应的类标签, 来确定对象对应的类可以允许完成这个操作, 即动态类型检查。此种方法在实际应用中, 虽然可以保证系统能够正常运行, 但是长时间运行会存在效率较低问题。基于此可以选择用静态类型检查, 即在对程序进行运行前, 需要对其进行全面分析, 确保某个标签检查操作能够正常运行, 则Java只会对其进行一次检查。否则, 若并不确定是否能够对某个标签检查操作成功, 则在程序载入前会报出错误。另外, Java系统运行安全还存在一个常见问题, 即类型混乱。一般Java系统会将对象看作为内存块, 被分配的内存包括一个接一个排列起来的所有对象数据域。一旦程序内某个指令需要引用某个对象时, 便需要一个确定目标地址的因素, 即类型标签。在此种运行程序下, 如果想要从根本上来确保Java系统安全性, 前提是要确定这个类型标签是否已经被恰当的标记。

2.2 语义分析

可以从三个方面来对Java进行语义分析, 即公共变量、被保护成员变量以及Java包。

2.2.1 公共变量

Java语法中对公共变量进行了定义, 其可以被任何Java类方法改写, 包括跨过命名空间且来自网络的Applet程序, 这就决定了公共变量中存储数据会存在一定的风险。

2.2.2 被保护成员变量

被保护成员变量能够被创造这个变量的类, 这个类所在包以及子类中所有成员访问。这样代码就可以通过验证自己身份权限, 确定自己是某个包成员而完成内部所有变量的访问。

2.2.3 Java包

系统仅仅给Java包提供了基本模板, 虽然其在命名空间表面上为分层状态, 但是Java包模板并不能成功嵌套。当能够成功嵌套模板时, 程序员才有权限限制安全敏感组件的可见性。

3 Java安全管理器分析

3.1 安全管理器概述

Java安全管理器可以为Java虚拟机环境建立一个防护作用的“沙箱”, 确保为程序的运行提供一个安全限制的操作环境, 如常见签名验证、定义安全策略以及安全管理器检查操作权限等, 来保证JVM外部资源的安全性, 避免受到JVM内部恶意代码的损坏。对于Java安全管理器来说, 其可以提供灵活性较高的安全策略, 以及细粒度访问控制, 授予不同资源访问权限, 最终构建成为Java程序安全机制。

3.2 安全机制类型

3.2.1 确认源文件安全

在确定源代码来源具有较高可靠性后, 向其分配相应操作权限。Java安全管理器能够为载入代码提供代码签名机制, 来保证代码避免在加载到本地虚拟机之前过程中被恶意篡改, 提高其安全性。

3.2.2 分配安全策略

即在Java安全管理器验证代码来源后, 向其分配相应安全策略。如安全策略可以为一个Java.sercurity.Policy的实现类, 其主要提供安全策略的定义与权限检查功能。同时, 由启动类加载器所加载核心类并不受安全管理器控制, 在实际应用中, 需要利用类加载器避免核心类被伪装代码替换。

3.3 Java沙箱

可以说Java沙箱为Java程序安全机制的核心, 对于Java程序来说, 其必须要在自己虚拟沙箱内执行, 来保证其运行安全性。其中JVM只向Java程序授予一组特定权限, 来对其系统其他部分的访问动作进行限制。Java沙箱主要是利用安全管理器来对各项权限进行检查, 并通过安全管理器来达到权限控制的目的, 除安全管理器外还包括访问控制器与策略文件两部分。在执行操作前, Java安全管理器确定是否允许执行此操作, 通过跑出Security Exception来拒绝此项操作, 但是大部分情况下其不会做出拒绝操作的最终决定, 而是通过访问控制器来检查。访问控制器对策略文件进行搜索, 最终确定是否允许执行此项操作。其中, 策略文件为一个文本文件, 可以通过任何文本编辑器进行编辑, 或者是选择用policytool GUI编辑策略文件。

4 结语

Java程序在实际应用中相对广泛, 结合程序运行环境特点进行分析, 为提高其运行安全性, 需要在现有基础上做更为深入的研究。即对程序安全机制运行方式进行分析, 掌握其要点, 遵循其运行原理来采取措施进行优化, 降低外界因素对程序运行环境的损坏。

参考文献

[1]杨哲慜.Java语言的程序漏洞检测与诊断技术[D].复旦大学, 2012.

[2]王晓亮.Java智能卡Applet安全下载机制的研究与实现[D].西安电子科技大学, 2009.

浅谈Java面向对象程序设计 篇8

1 类和对象

大千世界都是由一个个对象组成的,一张桌子,一幢房子,一个人,一辆汽车……都是对象,正所谓万物皆对象。然而把同一类对象的共同特征抽取出来用来描述这些对象的抽象集合就是类。对象的属性和行为抽象出来分别对应类的成员变量和方法。用个例子来说明,人的共同属性有性别、年龄、身高、体重等,共同行为有吃饭,睡觉,跑步等。把这些共同的属性和行为抽象为人这个类如下:

类集合抽象出来后,在程序中需要使用关键字new来创建对象。程序中一旦对象被创建出来,各类对象的“行为”就可以完成程序的各种功能。

2 封装性

封装性是为了隐藏类内部信息而创建出来的一种机制。其包含两层含义:

1)类是一个不可分割的单位,变量和对变量的操作组成了类。

2)类中必须提供对外联系的方法,但又得尽可能隐藏某些实现的细节。

为了实现隐藏类内部的信息,Java定义了类及其成员访问的四种权限修饰符:public(公有)、protected(保护)、default(默认)、private(私有)。

1)public修饰的成员,可以被程序中所有的类访问,它的访问权限是最低的。

2)protected修饰的成员,可以被类内部,同一包(package)中的类和其子类访问。

3)default修饰的成员,可以被类内部和同一个包中的类访问,其他地方的类都不可以访问,包括其子类。

4)Private修饰的成员,只能被类内部访问,由此实现类内部信息隐藏最重要的关键字是private,它的访问权限是最高的。

3 继承性

继承性是一种由已有的类创建新类的机制,是面向对象程序设计中实现软件可重用性的最重要手段。

3.1 继承的概念

由一个已有的类,通过使用关键字extends定义一个新类,称为新类继承了已有类。新类被称为子类或派生类,已有类被成为父类或基类。用个例子来说明:

3.2 继承的作用

通过继承,子类自动拥有父类的所有成员变量和方法(除构造方法),使得父类的优良特性得以代代相传并且大大减少了子类的代码量。继承是实现软件可重用性的一种重要方式,增强了软件的可扩充性,提高了软件的可维护性。对此我们在设计类时,一般将通用性功能设计在父类中,将特殊性功能设计在子类中。

3.3 继承的原则

1)只允许子类单继承和多层继承,不允许多继承。

2)子类可以增加自己的成员变量和方法。

3)子类可以重定义父类的成员变量和方法。

4 多态性

多态又称动态绑定,是指程序运行时,系统根据参数或对象的实际类型调用其相应的方法。方法的多态性主要有重载和覆盖。

4.1 方法重载

重载表现为同一个类中的多态性,同一个类中可以定义多个名字相同参数个数或参数类型不同的方法。程序在运行时,根据参数个数或参数类型,调用其相应的方法。

4.2 方法覆盖

覆盖又称重写,表现为父类与子类间的多态性。方法重写时应注意相应的原则:

1)重写方法必须和被重写方法具有相同的方法名,参数列表和返回值类型。

2)重写方法不能使用比被重写方法更严格的访问权限。

方法覆盖所表现出来的多态性必须具备以下条件:

1)要有继承。

2)要有重写。

3)父类引用指向子类对象。

5 结束语

面向对象思想的产生是编程语言发展史上质的飞跃,它使问题域中的各种关系明朗化,各类对象形象化。三大特征机制(封装性,继承性,多态性)使程序的设计更加严谨,结构更加清晰。

参考文献

[1]叶核亚.Java2程序设计实用教程[M].2版.北京:电子工业出版社,2007.

[2]马鲁宁.JAVA语言面向对象程序设计的特点[J].黑龙江科技信息,2007(2):52.

[3]笪斌,苏建元.实现面向对象的继承性、封装性和多态性[J].电脑学习,2005(6):18-19.

[4]孙巍.面向对象机制在Java中的运用[J].长春教育学院学报,2007(4):38-39.

Java程序设计的教学探讨 篇9

一、Java教学中存在的问题

在Java程序设计这门课程的教学中,通过多次与学生的交流、沟通,以及与同事之间的相互交流中,笔者发现该门课程在实际教学中主要存在以下几个方面的问题:

1.教材的选用不合适

当今市面上《Java程序设计》教程数不胜数,如何从琳琅满面的书中选一本合适的教材成为教师们首当其冲的问题。有些教程逻辑混乱,只讲究知识的全面性,简单的罗列知识点,而忽略其重点和知识的连惯性;有些教程实例陈旧,过于简单,不利于学生对知识的理解和把握。

2.教学对象分析的忽略

传统的备课只备教材,很少从学生本身去备课,不了解学生的现状,不知所需,学生则不能很好接受和消化知识,也容易遗忘知识。教师的备课是上好一堂课的前提,除了备教材以外还需备学生和学法。有了对学生的了解才能有的放矢。

3.教学内容的定位、目标不明确

Java程序设计内容颇多,对内容的筛选和把握不够。传统的教学只讲究知识的全面和系统,而忽视其实际应用。如程序设计语言中的运算符优先级的讲解,传统的教学花大量的时间来分析讲解,写一上一长串不加括号的运算符让学生写出其结果,这样学生感觉既枯燥又乏味。另外,传统的教学目标只重视学生对理论知识的掌握而轻视学生实际动手能力和创新精神。

4.教学重点偏颇

Java安排在C语言程序设计之后,虽然学生有一定的程序基础,但很多学生受面向过程设计思想的影响。在进行类设计的时候并没有体现面向对象的设计思想,不能深刻题解Java的核心思想。另外,Java的内容繁多,对重点和实用性的把握不够。

5.教学方法有待改进

传统的教学方法是单讲语法知识,而学生的注意力都被引导在具体的语法细节上,却忽略了在实际项目中的应用,结果导致学生会语法,不会编程用,使学生感觉学习这门课既“苦”又“枯”。程序设计本身就比较枯燥,对于理解能力和自控力相对较弱的学生更是吃不消。

6.实践环节较为薄弱和逻辑思维训练不够

Java程序设计是一门理论性和实践性非常强的课程,理论的理解需要实践的检验,实践反作用于理论,从而对概念和理论有进一步的理解。传统的教学对逻辑思维训练不够。

二、提高Java的教学途径

1.基本概念与恰当比喻相结合

Java程序设计的概念和基本原理比较多,如何让学生快速理解而又不容易遗忘,笔者在教学实践中采用概念与恰当的比喻相结合。比如在讲解如何来处理异常这一节时,举了一个大家都非常熟悉的例子——狼来了。小孩在放羊的过程中狼来了,这就是放养的过程中出现了异常,那么通常有两种做法:一是小孩迅速喊叫让大人们来处理,这就是将异常抛给别人来处理,即throws;另一种是自己处理,即try-catch-finally。

2.实践教学的改革思想

传统的教学模式概念语法知识讲的多,而实践的机会少,而且知识点和实践往往有脱节的现象,讲完知识点后学生不一定会用。笔者在教学实践中也是采用案例教学法[1],但这些例子是学生日常生活中最熟悉的例子,将所要讲解的知识点融入到项目实践中。比如在讲解数组这一节时,以一个计算学生成绩的小项目来展开,学生对计算成绩这事再也熟悉不过了,那么如何自己编写程序来计算呢?首先分析这一问题当中的关键词——成绩,成绩都是一些数值,而且可以说是同一类型的数据,在计算机内部如何来存放,由此引出数组的概念;对学生成绩通常需要计算机出总分、平均分和满足一定条件的成绩时,由此引出对数组的一些常用算法。

3.教学理念的改革

《国家中长期教育改革与发展规划纲要》中指出扩大应用型、技术型人才培养规模,为高校的培养目标指明了方向。因此在教学中应为目标做准备,体现应用型和技术型的特点,让学生真正学以致用、快速应用和适应技术的发展。在教学中应体现学习方法的传授,培养学生的自主学习能力和可持续学习的精神。另外,让学生在学生阶段多参与项目开发,提前进入全面应用阶段。

4.学生逻辑思维的训练

逻辑思维能力是计算机编程过程的一个至关重要的因素,任何程序都涉及到算法,如何开发快速有效和傻瓜式操作的应用软件,是程序员生命力的重要体现。在教学过程中帮助学生建立起这种思维,同时积累一定量的代码量。那么在实践教学中就应多分析算法、比较算法、改进算法和应用算法,逐步增强学生的逻辑思维能力。

5.完善评价机制

评价机制大多采用笔试和课程设计或答辩的形式[2],但在做课程设计时(如图书馆管理系统),大多也是要求学生提交纸质稿,不太方便检测学生的代码运行情况。笔者在实践中利用了学校的服务器,让学生连接服务器中的数据库,这样便于检测学生的代码运行状况。

结束语

当今社会发展日新月异,计算机技术更是如此,这就促使我们不断刷新教学方法和教学手段,促使学生理论水平和实践能力都有一个提高。

参考文献

[1]张洲平,安晓钢.Java程序设计的教学研究.中国科技创新导刊,2014(4):41-43.

Java程序设计中空对象的应用 篇10

关键词:多态,空对象,特殊对象,设计模式

1 引言

在程序设计的代码编写中, 在向对象发送一个消息 (也就是应用这个对象) 之前, 一般要检查对象是否存在, 这样的检查的场景很容易出现多次。比如在电信业务受理系统中, 可能会向一个业务受理对象索求它所相关的套餐对象, 然后再验证这个套餐对象是否为null;如果这个套餐对象存在, 才能调用它的资费方法来设置这个受理业务的资费, 在很多地方都是这样做的, 造成很多重复的代码, 空对象可以避免这样的情况。空对象的另一个应用场景是列表中的空对象和正常对象处理方式一样, 减少了空对象并且简化了处理。使用空对象带来的好处是系统从来不会因为空对象而被破坏, 由于空对象对所有外界请求的响应都和真实对象一样, 所以系统行为总是正常的。空对象还有一个特点就是一定是常量, 它们的任何属性都不会发生变化, 因此可以用单例模式来实现它们。下面就以实例来讲解在各种场景下的应用。

2 应用实例

现在有个应用是要计算汇总一个家庭所有成员名下的所有银行账户金额, 有的成员可能没有银行账户, 这里利用空对象技术, 就不用出现判断null的条件了, 详细的代码请见源代码文档, 这里只列出关键代码。

(1) 银行账户接口, 关键是要实现isNull () 方法。

(2) 如果没有银行账户, 就用NullBankAccount这个类来抽象, 用来建空对象。

(3) 正常的银行账户类, 用于创建正常的对象。

(4) 家庭成员接口, 家庭下的成员要实现这个接口。

(5) 家庭成员中的成年人, 成年人可以赚钱了, 有收入所以这里定为有银行账户。

(6) 家庭成员中的小孩子, 这里定为没有银行账户, 所以用NullBankAccount类来创建空对象。

(7) 计算家庭成员的所有收入总和, 在这里可以看到, 程序非常简洁, 没有与null的比较语句, 这里也不会出现null的异常场景。

3 结语

上一篇:新时代民生工程建设下一篇:慢性病人规范管理