文档库 最新最全的文档下载
当前位置:文档库 › 打造JAVA绿色程序

打造JAVA绿色程序

打造JAVA绿色程序
打造JAVA绿色程序

打造Java绿色程序

董洪蒙

(江苏淮安食品职业技术学院,江苏淮安223003)

摘要通过对Java运行时环境jre运行机理的深入分析,提出了如何解决Java程序发布问题的新思路,将其制作为符合软件发展潮流的绿色形式,大幅度削减jre的体积,以便于发布程序包的网络传递和存储。完成了核心程序的编写,综合运用了Java语言的多项知识点。

关键词绿色;jre;Process;Exception;Stream;jar

1引言

鉴于Windows系统对于Java采取的“彻底不合作”态度,Java程序作者经常面对如何在Windows平台下分发程序的问题,怎么保证目标机上有jre 呢?打包一个?一个jre几十Mb(笔者使用的j2sdk1.4.3_13的jre目录共计49.5Mb)。若是面向企业应用的大工程,这也就不成问题,但如果仅仅是一些面向桌面的应用程序,.class文件仅2-3Mb,就要带个几十Mb的jre,恐怕不仅用户难以满意,自己也觉得说不过去,更令人头疼的是:jdk版本众多,现在已发展至1.6以上版本,如果在用户机器上安装了多个Java程序,也就极有可能安装了多个jre版本,众所周知,多个jre版本在机器上共存,对于开发者来讲,需要很小心地处理,以避免出现各种莫名其妙的问题,而对于普通用户而言,版本间的冲突只会使其不明所以,徒增对程序作者甚至是Java的恶感。

笔者在长期工作过程中,深感软件行业越来越提倡开发、使用绿色软件,即一个软件应尽可能不影响系统、不影响其它软件,软件运行所需的动态库不在系统目录下共享,而是在自身目录下,删除该目录也即卸载了该软件,当然这个现象的背景是当今大容量磁盘的价格越来越低。Java程序要实现这种绿色的特性,其关键是:①要对.class文件和jre环境进行捆绑,置于同一目录下;

②要尽可能地对jre进行减肥,毕竟一个非企业级应用的软件动辄几十兆还是有些过分了。要解决这两点,首先要对jre的运行机理有深入理解,说得通俗一点:Java.exe运行时是如何找到jre,从而保证.class运行的?

2jre运行机理

众所周知java.exe是.class文件的执行程序,但实际上java.exe程序只是一个执行的外壳,它会装载jvm.dll,这个动态链接库才是Java虚拟机的实际操作处理所在,所以在这里要对jdk源代码作一番剖析,笔者这里使用的源

码版本是JavaTM2SDK,Standard Edition,v1.4.2fcs Community Source Release,主要分析的源文件为:j2se\src\share\bin\java.c。

java.c源代码中通过JAVA_ARGS宏来控制生成的代码,如果该宏没定义则编译文件控制生成java.exe,否则编译文件控制生成其他的“Java程序”,如javac.exe、javadoc.exe等。

java.c的main()函数中前面一段为重新分配参数指针的处理。然后调用函数:CreateExecutionEnvironment,该函数主要查找jre的目录,以及jvm.dll 这个虚拟机核心动态链接库文件路径所在。下面分而述之:

(1)查找jre路径,这主要是通过调用GetJREPath实现的。

该函数首先调用GetApplicationHome函数,GetApplicationHome函数调用windows API函数GetModuleFileName取java.exe程序的绝对路径,以我的jdk安装路径为例,为:“C:\j2sdk1.4.2_13\bin\java.exe”,然后去掉文件名取路径为:“C:\j2sdk1.4.2_13\bin”,之后会再去掉最后一级目录,现在路径为:“C:\j2sdk1.4.2_13”。

然后GetJREPath函数继续判断“C:\j2sdk1.4.2_13”路径+bin\ java.dll组合成的这个java.dll文件是否存在,如果存在则“C:

\j2sdk1.4.2_13”为jre路径(第1种情况:java.exe的父目录),否则判断取得的“C:\j2sdk1.4.2_13”路径+\jre\bin\java.dll文件是否存在,存在则“C:\j2sdk1.4.2_13\jre”为jre路径(第2种情况:java.exe父目录的子目录/jre/)。如果上面两种情况都不存在,则通过GetPublicJREHome函数从注册表中去查找。

GetPublicJREHome取得HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment中所含值名(ValueName)CurrentVersion的值(Value),这个值意为“当前jre版本号”,接着再取HKEY_LOCAL_MACHINE\Software\ JavaSoft\Java Runtime Environment\“当前jre版本号”中的值名JavaHome 所对应的值为jre路径(第3种情况),在笔者的机器上该值为“C:\Program Files\Java\j2re1.4.2_13”。

(2)确立jre路径后,下面就是如何定位jvm.dll的问题。

Java.c此时将调用函数ReadKnownVMs,该函数首先组合jvm.cfg文件的绝对路径,jre路径+\lib+\ARCH(CPU构架)+\jvm.cfg,在32位Windows系统上,就是jre路径\lib\i386\jvm.cfg。我们看到里面有如下字样:-client KNOWN

-server KNOWN

-hotspot ALIASED_TO–client

这也正是Java.exe可以支持的虚拟机相关参数,如果用-client或无参(默认)启动Java,则最终会使用jre路径\bin\client\下的jvm.dll,如果用-server,则最终启用的是jre路径\bin\server\下的jvm.dll,使用-hotspot 与-client效果一样。

至此,我们的应用程序才随着jvm.dll的载入而获得一个完全独立的虚拟机环境,从而得以执行。

我们已经对jre运行机制以及jvm.dll装载过程已经有了清晰的认识,在jdk

开发环境中的一些应用程序,如javac.exe、javadoc.exe等,实质上本身就是Java程序,其.exe文件只不过是特定Windows平台下的一个方便调用的包装器,

实际上它们都通过调用jdk目录\bin\java.exe(本目录无java.dll),来启动位于jdk目录\lib\tools.jar中的程序主体。在jdk目录下有一个jre子目录,里面正是jdk所带Java程序所使用的jre环境(符合我们上文分析的寻找jre

方法的第2种情况:java.exe父目录的jre子目录),从程序与jre捆绑在一起的情况来看,jdk本身就是一个不折不扣的绿色程序。另外jdk在安装时还有一个选项是否安装jre,这个jre与jdk目录下的jre子目录可没有任何关系,它主要由Windows系统目录(System32)下的java.exe、C:\Program

Files\java\jre目录、注册表的定位信息所组成,作用是提供一个在任何情况下均能启动.class(或.jar)程序的jre环境,这也符合上文分析的寻找jre的第3种方法。

我们实现Java绿色程序的第一步——进行程序和jre的捆绑,随着上文的分析,也就变得清晰起来:只要将jdk目录\jre\下的三个子文件夹:bin(本目录有java.dll)、javaws、lib拷贝到程序所有目录,并调用.\bin\java.exe 来启动自己的.class(.jar)即可,这样最终使用的肯定是该目录下的jre,这里我们套用的是定位jre的第1种情况:java.exe的父目录作为jre目录。

3精简jre

jre目录\lib\目录下数个jar文件:jce.jar、jsse.jar、rt.jar等,这些实际上就是Java基础类库文件,这几个文件的体积约占整个jre的70%左右,而其中尤以rt.jar最为突出,一个文件就有25-30兆之多,里面有几千个.class 类文件,其中的许多.class在程序里并未使用,所以要对jre进行减肥运动,就应该从缩减rt.jar入手,将不需要的.class文件删掉,最终与自己的应用程序集成在一起,打个包作为最终发布。

下面我们写一个HelloWorld来简单做个试验:

//D:\GreenJava\Helloworld.Java

public class Helloworld

{

public static void main(String[]argv)

{

System.out.println("Hello,World!");

try

{

Thread.currentThread().sle ep(10000);

}

catch(Exception e){}

}

}

进入D:\GreenJava,对其进行编译后执行Java–verbose

Helloworld(见图1)。

图1

在verbose模式下,可以清楚地看到本程序运行时需要的每个类从jre 的类库*.jar(大部分是rt.jar)中被调入内存的情况,基于Java的特性,每个类在jar中的路径与类名完全一致,可以很容易地从jar中提取出.class文件,至于如何获取程序运行时所需类的信息(光靠屏幕上人工记录肯定不行),进而如何根据这些信息从*.jar中提取出相关*.class等,运用一些编程技巧都能实现,请看程序:

//D:\GreenJava\GreenJava.Java

import Java.io.*;

import Java.util.*;

import Java.util.jar.*;

import Java.util.zip.*;

public class GreenJava

{

public static void main(String[]args)

throws IOException

{

int argv=args.length;

if(argv<=0)

{

System.out.println("参数个数太少");

System.exit(0);

}

String cmd="Java-verbose";

for(int i=0;i

cmd=cmd+""+args[i];

Process proc=Runtime.getRuntime().exec

(cmd);

BufferedReader reader=new

BufferedReader(new InputStreamReader

(proc.getInputStream()));

ArrayList list=new ArrayList();

while(true)

{

try

{

proc.exitValue();

}

catch(IllegalThreadStateException e)

{

String line=reader.readLine();

if(line!=null&&line.matches(

"\\[Loaded.*from.*"))

{

System.out.println("Matches:"+

line);

list.add(line.substring(8,

line.indexOf("from")));

}

continue;

}

break;

}

GreenJava gj=new GreenJava();

gj.buildJar(list,"D:/rt.jar");

}

public void buildJar(ArrayList lst,String

fileName)throws IOException

{

if(lst.size()==0)

return;

File f=new File(fileName);

if(!f.exists())

{

f.createNewFile();

}

byte[]buf=new byte[1024];

JarOutputStream out=new

JarOutputStream(new FileOutputStream

(fileName));

Iterator it=lst.iterator();

String s;

while(it.hasNext())

{

s=(String)it.next();

System.out.println("adding:"+s+".class");

s=s.replace('.','/')+".class";

InputStream in=this.getClass()

.getClassLoader()

.getResourceAsStream(s);

out.putNextEntry(new ZipEntry(s));

int w=in.read(buf);

while(w>=0)

{

out.write(buf,0,w);

w=in.read(buf);

}

in.close();

}

out.finish();

out.close();

}

}

编译好D:\GreenJava\GreenJava.Java后,进入目录后可以这样调用:Java GreenJava Helloworld,最后在D:\生成针对Helloworld程序所定制的rt.jar迷你版,Helloworld正常运行所需的类全部囊括其中,一个不少,一个不多。这个rt.jar在笔者机器生成大小为477Kb,缩减幅度惊人。

GreenJava.Java程序主要分为两大块:main(),它的主要功能是实现程序的入口,并且对目标程序(Helloworld)做一次完整地跟踪,撷取其运行时所真正需要类的信息,并记载于ArrarList中。BuildJar()根据ArrayList信息,从jre的类库(主要是rt.jar)中将相关的.class剥离出来,并最终形成能保证目录程序运行所需的迷你版rt.jar(D:\)。

在程序的main()部分,目标程序名经由命令行传递而来,在后台以冗余方式(verbose)启动目标程序为另一进程,并且利用Process的getInputStream 获得了该进程的标准输出,即图1所示的调用类列表。在while循环中,利用String的正则表达式匹配方法matchs("\\[Loaded.*from.*"]不断获取目标程序动态装载类的信息,并记录于ArrayList,同时使用了一个少见的技巧,即利用Java的Exception特性,来监控目标程序进程是否结束,未结束继续循环,结束则while也随之终止,并将ArrayList传递给buildJar。

在程序的buildJar()部分,则根据ArrayList的记录,使用类装配器(这里是GreenJava的AppClassLoader)从jre类库中取得相关类的字节流,并输出到自己的jar(zip结构)中。应特别注意的是:前后有两个Java程序在运行(GreenJava和Helloworld),使用的是同一套jre,因而能保持高度的一致性。

4其它一些问题

如前所述,将jre目录的三个子目录bin、Javaws、lib拷贝到Helloworld.class所在目录GreenJava,删除lib子目录下的*.jar,将D:\的迷你版rt.jar拷贝进去,再编写一个调用批处理:

rem D:\GreenJava\Helloworld.call.cmd

.\bin\Java-verbose Helloworld

双击执行后看一下效果(图2)。

图2

每一行的后部表明此时调用的正是改造过的rt.jar,迷你版rt.jar在最大限度缩减体积的同时,也完全保证了程序的正常运行。

此时我们的整个GreenJava目录体积还有10兆左右,这主要是因为bin 还有大量的dll,lib还有一些字体和相关配套文件,对于本例的Helloworld

而言,这些大多是可以删除的,经笔者试验的结果,最终保留的文件结构如下:bin\

client\(含jvm.dll Xusage.txt)

hpi.dll Java.dll Java.exe verify.dll zip.dll lib\

i386\(含jvm.cfg)

rt.jar(迷你版)

Helloworld.class

Helloworld.call.cmd

加起来体积约1.93Mb,WinRAR打包后(约996Kb)在没有jre的机器上释放,完全能够独立运行。

当然,Helloworld只是很简单的程序,如果稍微复杂一点,如笔者开发的一套GUI程序,就需要保留bin下的约一半的dll和lib下的fonts子目录才能正常运行,并且缩减后的rt.jar达到1.14Mb,整个文件夹5.89Mb,WinRAR 打包后3.18Mb,也还是比较让人满意的。

参考文献

[1]Java2:The Complete Reference,Fifth Edition,Herbert Schildt(美).周志彬等译.Java2参考大全(第五版)[M].北京:电子工业出版社,2003

[2]王森.Java深度历险[M].武汉:华中科技大学出版社,2002

收稿日期:8月17日修改日期:8月17日

15个经典JAVA小程序集

import java.util.Scanner; public class Example1 { public static void main(String[] args) { Scanner sc=new Scanner(System.in);//输入一个数字 int score=sc.nextInt();//将数字放入整型score中 if(score>0)//if语句进行判断 { if(score>=90) { System.out.println("你很棒!"); } else if(score>=60&&score<90) { System.out.println("你很不错!"); } else System.out.println("你得加油!"); } else System.out.println("你输入的数字不正确!"); } } import java.util.Scanner; public class Example2 { public static void main(String[] args) { Scanner sc=new Scanner(System.in);//动态输入任意两个数int a=sc.nextInt();

int b=sc.nextInt(); if(a>b)//if语句比较大小 { System.out.println("你所输入的最大值:"+a); System.out.println("你所输入的最小值:"+b); } else if(a

java源代码经典入门案例—光环java编程培训机构

java源代码经典入门案例 class Demo { public static void main(String[] args) { System.out.println("hello E盘"); } } class Demo { public static void main(String[] args) { System.out.println("hello E盘"); } } /* 需求:练习一个hello world程序。 思路: 1,定义一个类,因为java程序都定义类中,java程序都是以类的形式存在的,类的形式其实就是一个字节码文件最终体现。 2,定义一个主函数。为了让该类可以独立运行。 3,因为演示hello world,在控制台上看到该字样,所以需要使用输出语句完成。 步骤: 1,用class关键字来完成类的定义,并起一个阅读性强的类名。 2,主函数:public static void main(String[] args)这时固定格式的。jvm认识。 3,使用输出语句:System.out.println("hello world"); 代码仅仅是思想的一种体现形式。 */ class Demo

{ //定义一个主函数,为了保证程序的独立运行。 public static void main(String[] args) { System.out.println("hello world");//这是输出语句,用于将括号中的数据打印到控制台上,ln可以在数据的结尾处换行。 } } class OperateDemo { public static void main(String[] args) { //算术运算符。+ - * / %(取余,模运算) +(连接符) // ++(自增:就在原有数据基础上+1,在赋给原有数据) -- //int x = 6370; //x = x / 1000 * 1000; //System.out.println(x); // System.out.println(5%2); // System.out.println(3+"2"); //System.out.println("5+5="+(5+5));//"5+5=5"+5 "5+5=55" //int a = 4,b = 5; //System.out.println("a="+a+",b="+b);//a=4,b=5; int a = 3,b; //a++;//a = a+1; // b = a++; b = (a++)+(++a)+(a++)+a; // 3 5 5 6 System.out.println("a="+a+",b="+b); int i = 3; i = i++;

java经典编程题二及详细答案

2.1上机练习 ?基本题 1)编程观察如下输出语句: System.out.println("hello test escape char"); 在“escape”处换上各种转义字符测试输出效果。如何实现如下输出: Hello "test" Hello ‘\test’ 2)设有如下代码段,考虑赋值转换问题: int a=234; byte b=a; System.out.println("a=" a ",b=" b); 将a,b的类型以及数据进行各种替换,观察什么时候能赋值,什么时候需要使用强制转换,什么时候不能强制转换,什么时候强制转换会丢失数据。 3) 编写一个程序求半径R为10的圆的面积,结果保留2为有效小数。公式为:S=πR2 注:π可用Math类的常量PI表示(即Math.PI)。保留小数请查阅DecimalFormat类?提高题 1)设有一个边长为30的等边三角形,三角形内有一个内切圆,计算除内切圆外三角形内其它部分的面积。 【提示】先算三角形面积,再计算圆的面积,其差即为结果。h是等边三角形的高,内切圆的半径r=h/3,面积s=πh?/9。 2)调试分析以下程序的运行结果: public class test { public static void main(String a[]) { int m=10,n=517; System.out.println(n % m); System.out.println(n / m); System.out.println(m >> 2); System.out.println(m & n); System.out.println(Integer.toBinaryString(m)); System.out.println(Integer.toBinaryString(m >> 2)); } } 注意:Integer.toBinaryString(int)用于将一个整数转化为二进制形式的数字串。在进行位运算

java经典的小程序详尽代码

1,编写程序,判断给定的某个年份是否是闰年。 闰年的判断规则如下: (1)若某个年份能被4整除但不能被100整除,则是闰年。 (2)若某个年份能被400整除,则也是闰年。 import Bissextile{ public static void main(String[] arge){ "请输入年份"); int year; .....+aaaaaaaaa=? 其中a为1至9之中的一个数,项数也要可以指定。 import Multinomial{ public static void main(String[] args){ int a; ...前20项之和? class Sum{ public static void main(Sting[] args){ double sum=0; double fenZi=, fenMu=; ..... 打印出第一个大于小于的值 class Pi { public static void main(String[] args){ double pi =0; .. fenMu += ; .. 每项递加2 } } } 输出结果为pi = ,应该不精确 12、输入一个数据n,计算斐波那契数列(Fibonacci)的第n个值 1 1 2 3 5 8 13 21 34 规律:一个数等于前两个数之和 ....的值。 a,求出前50项和值。 b,求出最后一项绝对值小于1e-5的和值。 15、在屏幕上打印出n行的金字塔图案,如,若n=5,则图案如下: * ***

***** ******* ********* 定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,然后求出所有元素的最大值,最小值,平均值,和值,并输出出来。 class ArrayNumber{ public static void main(String[] args){ int[] arrayNumber; arrayNumber = new int[10]; "以下是随机的10个整数:"); 义一个int型的一维数组,包含10个元素,分别赋值为1~10,然后将数组中的元素都向前移一个位置, 即,a[0]=a[1],a[1]=a[2],…最后一个元素的值是原来第一个元素的值,然后输出这个数组。 3. 定义一个int型的一维数组,包含40个元素,用来存储每个学员的成绩,循环产生40个0~100之间的随机整数, 将它们存储到一维数组中,然后统计成绩低于平均分的学员的人数,并输出出来。 4. (选做)承上题,将这40个成绩按照从高到低的顺序输出出来。 5,(选做)编写程序,将一个数组中的元素倒排过来。例如原数组为1,2,3,4,5;则倒排后数组中的值 为5,4,3,2,1。 6,要求定义一个int型数组a,包含100个元素,保存100个随机的4位数。再定义一个 int型数组b,包含10个元素。统计a数组中的元素对10求余等于0的个数,保存到b[0]中;对10求余等于1的个数,保存到b[1]中,……依此类推。 class Remain{ public static void main( String[] args){ int[] a = new int[100]; 约梭芬杀人法 把犯人围成一圈,每次从固定位置开始算起,杀掉第7个人,直到剩下最后一个。 11_2、用数组实现约瑟夫出圈问题。 n个人排成一圈,从第一个人开始报数,从1开始报,报到m 的人出圈,剩下的人继续开始从1报数,直到所有的人都出圈为止。对于给定的n,m,求出所有人的出圈顺序。 12. 判断随机整数是否是素数 产生100个0-999之间的随机整数,然后判断这100个随机整数哪些是素数,哪些不是? public class PrimeTest{ public static void main(String args[]){ for(int i=0;i<100;i++){

Java经典编程题50道

【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一 对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分析:兔子的规律为数列1,1,2,3,5,8,13,21.... 【程序2】 题目:判断101-200之间有多少个素数,并输出所有素数。 1.程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除, 则表明此数不是素数,反之是素数。 【程序3】 题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。例如: 153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。 1.程序分析:利用for循环控制100-999个数,每个数分解出个位,十位,百位。 【程序4】 题目:将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。 程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成: (1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。 (2)如果n<>k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数你n,重复执行第一步。 (3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。 【程序5】 题目:利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下 的用C表示。 1.程序分析:(a>b)?a:b这是条件运算符的基本例子。 【程序6】 题目:输入两个正整数m和n,求其最大公约数和最小公倍数。 1.程序分析:利用辗除法。 【程序7】 题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。 1.程序分析:利用while语句,条件为输入的字符不为'\n'. 【程序8】 题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加), 几个数相加有键盘控制。 1.程序分析:关键是计算出每一项的值。 【程序9】

50道经典java编程题

【程序1】TestRabbit.java 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 【程序2】FindPrimeNumber.java 题目:判断101-200之间有多少个素数,并输出所有素数。 【程序3】FindDaffodilNumber.java 题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。例如: 153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。 【程序4】FenJie.java 题目:将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。 【程序5】ConditionOperator.java 题目:利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。

【程序6】GcdTest.java辗转相除法 题目:输入两个正整数m和n,求其最大公约数和最小公倍数。 【程序7】StChar.java 题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。 【程序8】TestAdd.java 题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。 【程序9】WanShu.java 题目:一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如6=1+2+3.编程找出1000以内的所有完数。 【程序10】TestBall.java 题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?

java经典小程序模板

JA V A经典小程序1,编写程序,判断给定的某个年份是否是闰年。 闰年的判断规则如下: (1)若某个年份能被4整除但不能被100整除,则是闰年。 (2)若某个年份能被400整除,则也是闰年。 import java.util.Scanner; class Bissextile{ public static void main(String[] arge){ System.out.print("请输入年份"); int year; //定义输入的年份名字为“year” Scanner scanner = new Scanner(System.in); year = scanner.nextInt(); if (year<0||year>3000){ System.out.println("年份有误,程序退出!"); System.exit(0); } if ((year%4==0)&&(year%100!=0)||(year%400==0)) System.out.println(year+" is bissextile"); else System.out.println(year+" is not bissextile "); } } 2,给定一个百分制的分数,输出相应的等级。 90分以上A级 80~89 B级 70~79 C级 60~69 D级 60分以下E级 import java.util.Scanner; class Mark{ public static void main(String[] args){ System.out.println("请输入一个分数"); //定义输入的分数为“mark”,且分数会有小数 double mark; Scanner scanner = new Scanner(System.in); mark = scanner.nextDouble(); //判断是否有输入错误。

若干个经典的Java小程序源代码

一个Java小程序源代码(反转字符串)//BorderLayoutTest.java import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; public class test1 { public static void main(String[] args) { cloneFrame frame = new cloneFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.show(); } } class cloneFrame extends JFrame { public cloneFrame() {

setTitle("机试程序"); setSize(600, 400); JPanel buttonPanel = new JPanel(); buttonPanel.setBackground(new Color(56,43,85)); Button1 = new JButton("点击复制反转字符串"); Button1.addActionListener(new turnListener()); buttonPanel.add(Button1); JPanel textPanel = new JPanel(); textPanel.setBackground(new Color(100,100,100)); field1 = new JTextField("姓名:老孙;学号:2004132028", 20); field2 = new JTextField("反转", 20); field2.setEditable(false); textPanel.add(field1); textPanel.add(field2); JPanel tuPanel = new JPanel();

Java经典练习题

Java基础试题 一、选择题 1.编译Java Application 源程序文件将产生相应的字节码文件,这些字节码文件的扩展名为( B )。 A. .java B. .class C. .html D. .exe 2、设x = 1 , y = 2 , z = 3,则表达式y+=z--/++x 的值是( A )。 A. 3 B. 3. 5 C. 4 D. 5 3、main方法是Java Application程序执行的入口点,关于main方法的方法头以下哪项是合法的(B)? A、public static void main() B、public static void main(String args[] ) C、public static int main(String [] arg ) D、public void main(String arg[] )4 4.Which of the following is not a valid comment:D a. /** comment */ b. /* comment */ c. /* comment d. // comment 5. Java中char类型的数据长度为 :C (A)8位(B)16位(C)32位(D)64位 6.下面哪个表达式是错误的:B (A)int i = 100; (B)float f = 100.0; (C)Object o = “Hello world”; (D)char c = ‘\u1234’; 7.下面哪个语句是正确的:C (A)byte s = 256; (B)String s = ‘Hello world’; (C)int x = 012; (D)char c = “a”; 8.下列叙述中,正确的是:A A)声明变量时必须指定一个类型 B)Java认为变量number与Number相同 C)Java中唯一的注释方式是"//" D)源文件中public类可以有0或多个 9.下列属于合法的Java标识符是:D A)"ABC" B)&5678 C)+rriwo D)saler 10.下面哪个标识符是不合法的:D (A)s1 (B)$1 (C)_1 (D)1s 11.在switch(expression)语句中,expression的数据类型不能是:A A)double B)char C)byte D)short 12.已知:int[] a = new int[100];在下列给出的数组元素中,非法的是:D A)a[0] B)a[1] C)a[99] D)a[100] 13.下列的哪个赋值语句是不正确的?: A A.float f = 11.1; B.double d = 5.3E12;

Java编程五大经典实例(初学者版)

一、实验目的: 1、掌握 Java 基本数据类型、运算符与表达式、数组和字符串的使用方法。 2、掌握各种变量的声明方式。 3、理解 Java 程序语法结构,掌握顺序结构、选择结构和循环结构语法的程序设计方法。 4、通过以上内容,掌握 Java 语言的编程规则。 5、了解Java程序文件名和类名的说明方法。 二、实验内容(或步骤)提要 1、输入一个学生的成绩,给出相应的等级(分别用if和switch语句实现)。 85分及以上为A级;70分及以上为B级; 60分及以上为C级;60分以下为D级。 【参考程序1】 public class Score{ public static void main(String args[]){ int s=Integer.parseInt(args[0]); if(s<60) System.out.println("D"); else if(s<70) System.out.println("C"); else if(s<85) System.out.println("B"); else System.out.println("A"); } } 【参考程序2】 public class Score{ public static void main(String args[]){ int s=Integer.parseInt(args[0]); int x=s/10; switch (x) { case 0: case 1: case 2: case 3: case 4:

case 5: System.out.println("D");break; case 6: System.out.println("C");break; case 7: case 8: if (s <85) { System.out.println("B"); break; } case 9: case 10: System.out.println("A"); } } } 2、输入某人的应纳税所得额,计算个人所得税。税率表如下: 级数全月应纳税所得额税率%速算扣除法(元) 1不超过500元的50 2超过500元至2000元的部分10 25 3超过2000元至5000元的部分15 125 4超过5000元至20000元的部分20 375 5 超过20000元至40000元的部分251375 6 超过40000元至60000元的部分30 3375 7 超过60000元至80000元的部分356375 8 超过80000元至100000元的部分40 10375 9 超过100000元的部分45 15375 计算公式是:应纳个人所得税税额=应纳税所得额×适用税率-速算扣除数 例:王某当月应纳税所得额6400元。则应纳个人所得税税额=6400×20%-375=905元。【参考程序】 import java.util.Scanner; public class TaxCompute {

Java100个经典小程序

【程序1】 题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去掉不满足条件的排列。 ============================================================== 【程序2】 题目:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数? 程序分析:请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。 ============================================================== 【程序3】 题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? 程序分析:在10万以内判断,先将该数加上100后再开方,再将该数加上268后再开方,如果开方后的结果满足如下条件,即是结果。 ============================================================== 【程序4】 题目:输入某年某月某日,判断这一天是这一年的第几天? 程序分析:以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本年的第几天,特殊情况,闰年且输入月份大于3时需考虑多加一天。 ============================================================== 【程序5】 题目:输入三个整数x,y,z,请把这三个数由小到大输出。 程序分析:我们想办法把最小的数放到x上,先将x与y进行比较,如果x>y则将x与y的值进行交换,然后再用x与z进行比较,如果x>z则将x与z的值进行交换,这样能使x最小。 ============================================================== 【程序6】 题目:输出9*9口诀。 程序分析:分行与列考虑,共9行9列,i控制行,j控制列。 ============================================================== 【程序7】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 程序分析:兔子的规律为数列1,1,2,3,5,8,13,21.... ============================================================== 【程序8】 题目:判断101-200之间有多少个素数,并输出所有素数。 程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。 ============================================================== 【程序9】 题目:打印出所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个“水仙花数”,因为153=1的三次方+5的三次方+3的三次方。 程序分析:利用for循环控制100-999个数,每个数分解出个位,十位,百位。 ============================================================== 【程序10】

java经典选择题100例及答案

1.使用Java语言编写的源程序保存时的文件扩展名是()。 (A).class (B).java (C).cpp (D).txt 2.设int a=-2,则表达式a>>>3的值为()。 (A)0 (B)3 (C)8 (D)-1 3.设有数组的定义int[] a = new int[3],则下面对数组元素的引用错误的是()。 (A)a[0]; (B)a[a.length-1]; (C)a[3]; (D)int i=1;a[i]; 4.在类的定义中可以有两个同名函数,这种现象称为函数()。 (A)封装(B)继承 (C)覆盖(D)重载 5.在类的定义中构造函数的作用是()。 (A)保护成员变量(B)读取类的成员变量 (C)描述类的特征(D)初始化成员变量 6.下面关键字中,哪一个不是用于异常处理语句()。 (A)try (B)break (C)catch (D)finally 7.类与对象的关系是()。 (A)类是对象的抽象(B)对象是类的抽象 (C)对象是类的子类(D)类是对象的具体实例 8.下面哪一个是Java中不合法的标识符()。 (A)$persons (B)twoNum (C)_myVar (D)*point 9.为AB类的一个无形式参数无返回值的方法method书写方法头,使得使用类名AB作为前缀就可以调用它,该方法头的形式为( )。 (A)static void method( ) (B)public void method( ) (C)final void method( ) (D)abstract void method( ) 10.欲构造ArrayList类的一个实例,此类继承了List接口,下列哪个方法是正确的()。 (A)ArrayList myList=new Object( ) (B)List myList=new ArrayList( ) (C)ArrayList myList=new List( ) (D)List myList=new List( ) 11.Java源文件和编译后的文件扩展名分别为() (A) .class和.java(B).java和.class (C).class和.class(D) .java和.java 12.在Java Applet程序用户自定义的Applet子类中,一般需要重载父类的( )方法来完成一些画图操作。 (A) start( ) (B) stop( ) (C) init( ) (D) paint( ) 13.对于一个Java源文件,import, class定义以及package正确的顺序是: (A) package,import,class(B) class,import,package (C) import,package,class(D) package,class,import 14.下面哪个是非法的: (A) int I = 32;(B) float f = 45.0; (C) double d = 45.0;(D) char c = ‘u’;//符号错 15.Java语言使用的字符码集是 (A) ASCII (B) BCD (C) DCB (D) Unicode 16. 如果一个类的成员变量只能在所在类中使用,则该成员变量必须使用的修饰是 (A) public (B) protected (C) private (D) static 17.下面关于main方法说明正确的是 (A) public main(String args[ ]) (B) public static void main(String args[ ]) (C) private static void main(String args[ ]) (D) void main() 18.哪个关键字可以对对象加互斥锁?( ) (A) transient (B) synchronized (C) serialize (D) static 19.关于抽象方法的说法正确的是( ) (A)可以有方法体(B) 可以出现在非抽象类中 (C) 是没有方法体的方法(D) 抽象类中的方法都是抽象方法 20.java.io包的File类是 (A)字符流类(B) 字节流类 (C) 对象流类(D) 非流类 21.Java application中的主类需包含main方法,以下哪项是main方法的正确形参?() A、String args B、String args[] C、Char arg D、StringBuffer args[] 22.以下代码段执行后的输出结果为()A、-1 B、2 C、1 D、3 23.以下关于继承的叙述正确的是()。 A、在Java中类只允许单一继承 B、在Java中一个类只能实现一个接口 C、在Java中一个类不能同时继承一个类和实现一个接口 D、在Java中接口只允许单一继承 24. 若有定义:byte[] x={11,22,33,-66}; 其中0≤k≤3,则对x数组元素错误的引用是() A)x[5-3] B)x[k] C)x[k+5] D)x[0] 25.paint()方法使用哪种类型的参数? () A、Graphics B、Graphics2D C、String D、Color 26.以下哪个不是Java的原始数据类型() A、int B、Boolean C、float D、char 27.在Java中,一个类可同时定义许多同名的方法,这些方法的形式参数的个数、类型或顺序各不相同,传回的值也可以不相同。这种面向对象程序特性称为() A)隐藏 B)重写 C)重载 D)Java不支持此特性 28.以下有关构造方法的说法,正确的是:() A.一个类的构造方法可以有多个 B.构造方法在类定义时被调用 C.构造方法只能由对象中的其它方法调用。 D.构造方法可以和类同名,也可以和类名不同 29.在浏览器中执行applet 程序,以下选项中的哪个方法将被最先执行()。 A、init() B、start() C、destroy() D、stop() 30.给出下面代码,关于该程序以下哪个说法是正确的?()public class Person{ static int arr[] = new int[5]; public static void main(String a[]) { System.out.println(arr[0]);} } A、编译时将产生错误 B、编译时正确,运行时将产生错误 C、输出零 D、输出空 31、有以下方法的定义,请选择该方法的返回类型()。ReturnType method(byte x, double y) { return (short)x/y*2; } A、byte B、short C、int D、double 32.下列类定义中哪些是合法的抽象类的定义?() A、abstract Animal{abstract void growl();} B、class abstract Animal{abstract void growl();} C、abstract class Animal{abstract void growl();} D、abstract class Animal{abstract void growl(){System.out.println(“growl”);};} 33.有以下程序片段,下列哪个选项不能插入到行1。() 1. 2.public class Interesting{ 3.//do sth 4. } A、import java.awt.*; B、package mypackage; C、class OtherClass{ } D、public class MyClass{ } 34. 设有下面两个赋值语句: a = Integer.parseInt(“12”); b = Integer.valueOf(“12”).intValue(); 下述说法正确的是()。 A、a是整数类型变量,b是整数类对象。 B、a是整数类对象,b是整数类型变量。 C、a和b都是整数类对象并且值相等。 D、a和b都是整数类型变量并且值相等。 35.在编写Java Applet程序时,需在程序的开头写上( )语句。 A、import java.awt.* ; B、import java.applet.Applet ; C、import java.io.* ; D、import java.awt.Graphics ; 36.下列哪一项不属于Swing的顶层容器?()

JAVA中经典快捷键(必看)和一些程序代码

Eclipse 常用快捷键 Eclipse的编辑功能非常强大,掌握了Eclipse快捷键功能,能够大大提高开发效率。Eclipse中有如下一些和编辑相关的快捷键。 1. 【ALT+/】 此快捷键为用户编辑的好帮手,能为用户提供内容的辅助,不要为记不全方法和属性名称犯愁,当记不全类、方法和属性的名字时,多体验一下【ALT+/】快捷键带来的好处吧。 2. 【Ctrl+O】 显示类中方法和属性的大纲,能快速定位类的方法和属性,在查找Bug时非常有用。 3. 【Ctrl+/】 快速添加注释,能为光标所在行或所选定行快速添加注释或取消注释,在调试的时候可能总会需要注释一些东西或取消注释,现在好了,不需要每行进行重复的注释。 4. 【Ctrl+D】 删除当前行,这也是笔者的最爱之一,不用为删除一行而按那么多次的删除键。 5. 【Ctrl+M】 窗口最大化和还原,用户在窗口中进行操作时,总会觉得当前窗口小(尤其在编写代码时),现在好了,试试【Ctrl+M】快捷键。 查看和定位快捷键 在程序中,迅速定位代码的位置,快速找到Bug的所在,是非常不容易的事,Eclipse 提供了强大的查找功能,可以利用如下的快捷键帮助完成查找定位的工作。 1. 【Ctrl+K】、【Ctrl++Shift+K】 快速向下和向上查找选定的内容,从此不再需要用鼠标单击查找对话框了。 2. 【Ctrl+Shift+T】 查找工作空间(Workspace)构建路径中的可找到Java类文件,不要为找不到类而痛苦,而且可以使用“*”、“?”等通配符。 3. 【Ctrl+Shift+R】

和【Ctrl+Shift+T】对应,查找工作空间(Workspace)中的所有文件(包括Java文件),也可以使用通配符。 4. 【Ctrl+Shift+G】 查找类、方法和属性的引用。这是一个非常实用的快捷键,例如要修改引用某个方法的代码,可以通过【Ctrl+Shift+G】快捷键迅速定位所有引用此方法的位置。 5. 【Ctrl+Shift+O】 快速生成import,当从网上拷贝一段程序后,不知道如何import进所调用的类,试试【Ctrl+Shift+O】快捷键,一定会有惊喜。 6. 【Ctrl+Shift+F】 格式化代码,书写格式规范的代码是每一个程序员的必修之课,当看见某段代码极不顺眼时,选定后按【Ctrl+Shift+F】快捷键可以格式化这段代码,如果不选定代码则默认格式化当前文件(Java文件)。 7. 【ALT+Shift+W】 查找当前文件所在项目中的路径,可以快速定位浏览器视图的位置,如果想查找某个文件所在的包时,此快捷键非常有用(特别在比较大的项目中)。 8. 【Ctrl+L】 定位到当前编辑器的某一行,对非Java文件也有效。 9. 【Alt+←】、【Alt+→】 后退历史记录和前进历史记录,在跟踪代码时非常有用,用户可能查找了几个有关联的地方,但可能记不清楚了,可以通过这两个快捷键定位查找的顺序。 10. 【F3】 快速定位光标位置的某个类、方法和属性。 11. 【F4】 显示类的继承关系,并打开类继承视图。 调试快捷键 Eclipse中有如下一些和运行调试相关的快捷键。

Java经典基础代码

Monkey_peach代码 package com.sailor.game; /** * 题目:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个第二天早上又将剩 * 下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。 * 程序分析:采取逆向思维的方法,从后往前推断。 * * @author Sailor * */ public class Monkey_Peach { public static void main(String[] args) { int[] peach = new int[10]; peach[9] = 1; // 下面利用的是数组和循环将每天的桃子数量都求出来了 for (int i = peach.length - 1; i > 0; i--) { peach[i - 1] = 2 * (peach[i] + 1); } for (int i = 0; i < peach.length; i++) { System.out.println(peach[i]); } System.out.println("第一天的桃子数:"+getPeach_Num(10, 1)); } // 利用递归的方法来求第一天的桃子数,输入参数为天数和当天的桃子数,输出为第一天桃子数 public static int getPeach_Num(int day, int peach_num) { if (day == 1) return peach_num; else if (day < 1 || peach_num < 0) return 0; else return getPeach_Num(day - 1, (peach_num + 1) * 2); }

10道经典java编程笔试题

10道经典java编程笔试题 【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少 //这是一个菲波拉契数列问题 public class lianxi01 { public static void main(String[] args) { System.out.println("第1个月的兔子对数: 1"); System.out.println("第2个月的兔子对数: 1"); int f1 = 1, f2 = 1, f, M=24; for(int i=3; i<=M; i++) { f = f2; f2 = f1 + f2; f1 = f; System.out.println("第" + i +"个月的兔子对数: "+f2); } } } 【程序2】 题目:判断101-200之间有多少个素数,并输出所有素数。 程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。 public class lianxi02 { public static void main(String[] args) { int count = 0; for(int i=101; i<200; i+=2) { boolean b = false; for(int j=2; j<=Math.sqrt(i); j++) { if(i % j == 0) { b = false; break; } else { b = true; } } if(b == true) {count ++;System.out.println(i );} } System.out.println( "素数个数是: " + count);

相关文档
相关文档 最新文档