javap是JDK自带的反汇编器,可以查看java编译器为我们生成的字节码。通过它,我们可以对照源代码和字节码,从而了解很多编译器内部的工作。
语法:
javap [ 命令选项 ] class. . .
javap 命令用于解析类文件。其输出取决于所用的选项。若没有使用选项,javap 将输出传递给它的类的 public 域及方法。javap 将其输出到标准输出设备上。
命令选项
-help 输出 javap 的帮助信息。
-l 输出行及局部变量表。
-b 确保与 JDK 1.1 javap 的向后兼容性。
-public 只显示 public 类及成员。
-protected 只显示 protected 和 public 类及成员。
-package 只显示包、protected 和 public 类及成员。这是缺省设置。
-private 显示所有类和成员。
-J[flag] 直接将 flag 传给运行时系统。
-s 输出内部类型签名。
-c 输出类中各方法的未解析的代码,即构成 Java 字节码的指令。
-verbose 输出堆栈大小、各方法的 locals 及 args 数,以及class文件的编译版本
-classpath[路径] 指定 javap 用来查找类的路径。如果设置了该选项,则它将覆盖缺省值或 CLASSPATH 环境变量。目录用冒号分隔。
- bootclasspath[路径] 指定加载自举类所用的路径。缺省情况下,自举类是实现核心 Java 平台的类,位于 jrelib
t.jar 和 jrelibi18n.jar 中。
-extdirs[dirs] 覆盖搜索安装方式扩展的位置。扩展的缺省位置是 jrelibext。
例:
public class Test {
public static void main(String[] args) {
System.out.println("hello world!");
}
}
然后再执行以下命令:
javac Test.java
javap -c Test
得到如下结果:
Compiled from "Test.java"
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."":
()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/
io/PrintStream;
3: ldc #3 // String hello world!
5: invokevirtual #4 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
8: return
}
posted @
2015-03-05 14:25 marchalex 阅读(328) |
评论 (2) |
编辑 收藏
在java5中新增加了java.util.Queue接口,用以支持队列的常见操作。该接口扩展了java.util.Collection接口。
Queue使用时要尽量避免Collection的add()和remove()方法,而是要使用offer()来加入元素,使用poll()来获取并移出元素。它们的优点是通过返回值可以判断成功与否,add()和remove()方法在失败的时候会抛出异常。 如果要使用前端而不移出该元素,使用element()或者peek()方法。
值得注意的是LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。
import java.util.LinkedList;
import java.util.Queue;
public class QueueSample {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<String>();
queue.offer("Hello ");
queue.offer("World!");
System.out.println(queue.size());
String str;
while((str=queue.poll())!=null){
System.out.print(str);
}
System.out.println();
System.out.println(queue.size());
}
}
posted @
2015-03-05 10:32 marchalex 阅读(218) |
评论 (0) |
编辑 收藏
在之前我写过一个英汉翻译的java小程序
EnglishChineseTranslater,今天在原来的基础上加了一些改进。
TranalateMaster类用于翻译一个文件内的所有单词。
通过之前讲到的
文件操作进行文件内容的读取,再通过StringTokenizer来分词,最后一个一个的翻译。
这里有一个优化,就是通过HashMap来去重,这样可以优化文件中一些单词重复出现所消耗的时间。translateAll函数翻译并直接输出,translateAllLocal函数翻译并保存到本地。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.HashMap;
import java.util.StringTokenizer;
public class TranslateMaster {
private static HashMap<String, String> map = null;
public static void getWords(String filename) throws Exception {
map = new HashMap<String, String>();
BufferedReader reader = new BufferedReader(new FileReader(filename));
String line = null;
while((line = reader.readLine()) != null){
StringTokenizer st = new StringTokenizer(line, ",.-!? \t");
while(st.hasMoreElements()) {
String key = st.nextToken();
if(map.containsKey(key) == false) {
try {
String value = EnglishChineseTranslater.getWordName(key) + ": " + EnglishChineseTranslater.getTranslation(key);
map.put(key, value);
} catch (Exception e) {
continue;
}
}
}
}
reader.close();
}
public static void translateAll(String filename) throws Exception {
getWords(filename);
BufferedReader reader = new BufferedReader(new FileReader(filename));
String line = null;
while((line = reader.readLine()) != null){
StringTokenizer st = new StringTokenizer(line, ",.-!? \t");
while(st.hasMoreElements()) {
String key = st.nextToken();
System.out.println(map.get(key));
}
}
reader.close();
}
public static void translateAllLocal(String inputfilename, String outputfilename) throws Exception {
getWords(inputfilename);
BufferedReader reader = new BufferedReader(new FileReader(inputfilename));
BufferedWriter writer = new BufferedWriter(new FileWriter(outputfilename));
String line = null;
while((line = reader.readLine()) != null){
StringTokenizer st = new StringTokenizer(line, ",.-!? \t");
while(st.hasMoreElements()) {
String key = st.nextToken();
writer.write(map.get(key) + "\r\n");
//System.out.println(map.get(key));
}
}
writer.close();
reader.close();
}
public static void main(String[] args) throws Exception {
translateAll("D:\\test.txt");
translateAllLocal("D:\\test.txt", "D:\\output.txt");
}
}
输入文件中的内容为:
an apple a day,keep healthy a way.
输出结果显示为:
an: 一(在元音字母前代替不定代词a);一任一某一;一个
apple: 苹果;苹果树;苹果公司
a: 一(个);每一(个);任一(个)
day: 一天;白天;时期;节日
keep: 保持;保留;遵守;阻止
healthy: 健康的;健全的;大量的;有益于健康的
a: 一(个);每一(个);任一(个)
way: 道路;方法;方向;某方面
posted @
2015-03-04 14:21 marchalex 阅读(257) |
评论 (0) |
编辑 收藏
Java IO系统里读写文件使用Reader和Writer两个抽象类,Reader中read()和close()方法都是抽象方法。Writer中 write(),flush()和close()方法为抽象方法。子类应该分别实现他们。
Java IO已经为我们提供了三个方便的Reader的实现类,FileReader,InputStreamReader和BufferedReader。其中最重要的类是InputStreamReader, 它是字节转换为字符的桥梁。你可以在构造器重指定编码的方式,如果不指定的话将采用底层操作系统的默认编码方式,例如GBK等。
FileReader读txt文件例子
FileReader fr = new FileReader("D:\\test.txt");
int ch = 0;
while((ch = fr.read())!=-1 ){
System.out.print( (char)ch );
}
其中read()方法返回的是读取得下个字符。
InputStreamReader读txt文件例子
InputStream is = new FileInputStream(new File("D:\\test.txt"));
InputStreamReader reader = new InputStreamReader(is);
int ch = 0;
while((ch = reader.read())!=-1 ){
System.out.print((char)ch);
}
这和FileReader并没有什么区别,事实上在FileReader中的方法都是从InputStreamReader中继承过来的。 read()方法是比较好费时间的,如果为了提高效率,我们可以使用BufferedReader对Reader进行包装,这样可以提高读取得速度,我们可以一行一行的读取文本,使用 readLine()方法。
BufferedReader br = new BufferedReader(new FileReader("D:\\test.txt"));
String line = null;
while((line = br.readLine()) != null){
System.out.println(line);
}
当你明白了如何用Reader来读取文本文件的时候那么用Writer写文件同样非常简单。有一点需要注意,当你写文件的时候,为了提高效率,写入的数据会先放入缓冲区,然后写入文件。因此有时候你需要主动调用flush()方法。
有读就有写,写文本文件可以使用PrintWriter,FileWriter,BufferedWriter。
FileWriter fw = new FileWriter("D:\\test01.txt");
String s = "hello world!\n";
fw.write(s,0,s.length());
fw.flush();
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\test02.txt"));
osw.write(s,0,s.length());
osw.flush();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("D:\\test03.txt")),true);
pw.println(s);
fw.close();
osw.close();
pw.close();
如果想在文件末尾追加内容,声明加个true就加一个"true"就可以了:
FileWriter fw = new FileWriter("log.txt",true);
下面是一个BufferedWriter的例子:
File file = new File("D:\\test.txt");
File dest = new File("D:\\test01.txt");
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
BufferedWriter writer = new BufferedWriter(new FileWriter(dest));
String line = reader.readLine();
while(line!=null){
writer.write(line);
line = reader.readLine();
}
writer.flush();
reader.close();
writer.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
最后写的程序用于简单的文件读写操作。FileHelper类中的readFile方法用于读取文件内容,writeFile方法用于向文件中写入内容。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class FileHelper {
public static String readFile(String filename) throws Exception {
BufferedReader reader = new BufferedReader(new FileReader(filename));
String ans = "", line = null;
while((line = reader.readLine()) != null){
ans += line + "\r\n";
}
reader.close();
return ans;
}
public static void writeFile(String content, String filename) throws Exception {
BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
writer.write(content);
writer.flush();
writer.close();
}
public static void main(String[] args) throws Exception {
String ans = readFile("D:\\input.txt");
writeFile(ans, "D:\\output.txt");
}
}
posted @
2015-03-04 13:26 marchalex 阅读(280) |
评论 (0) |
编辑 收藏
通过对
金山在线词典的分析,我发现在他的词库里有的单词的url都是以"http://www.iciba.com/" + 单词 的形式出现的。
在之前我写过一个
获得网页源代码的代码,我在此基础上写了一个获得英文单词在iciba上面的获得单词翻译的程序,那么接下来先要查单词就可以不用打开浏览器那么麻烦了。
getWordName函数用于获得单词对应的实际单词,因为很有可能我要查的单词实际上是没有的,那么他就会跳转到另一个和这个单词表交响的单词的url上。
getTranslation函数用于获得单词的中文翻译。
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "utf-8"));这句话最后添加的"utf-8"解决了获取网页源代码里面的中文乱码问题。
代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class EnglishChineseTranslater {
public static String getWordName(String word) throws Exception {
String urlString = "http://www.iciba.com/" + word;
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "utf-8"));//"utf-8"解决中文乱码问题
String line;
String ans = "";
for(int i=0;i<8;i++) reader.readLine();
line = reader.readLine();
int len = line.length();
for(int i=len-4;i > 0 && line.charAt(i) != '/';i--)
ans = line.charAt(i) + ans;
return ans;
}
public static String getTranslation(String word) throws Exception {
String urlString = "http://www.iciba.com/" + word;
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "utf-8"));//"utf-8"解决中文乱码问题
String line;
String ans = "";
while ((line = reader.readLine()) != null){
line = line.trim();
if(line.equals("<span class=\"label_list\">")) {
while((line = reader.readLine()) != null) {
line = line.trim();
if(false == line.substring(0, 7).equals("<label>"))
break;
line = line.substring(7, line.length()-8);
//System.out.println(line);
ans += line;
}
break;
}
}
return ans;
}
public static void main(String[] args) throws Exception {
String word = "apple";
String trueWord = getWordName(word);
String translation = getTranslation(word);
System.out.println(trueWord + ": " + translation);
}
}
posted @
2015-03-03 17:11 marchalex 阅读(231) |
评论 (0) |
编辑 收藏
之前我在ScreenDemo类中用generateSnapshot()方法实现了对
当前屏幕的截图,这里在原来的基础上增加了printPointRGB方法用于获取屏幕上的某一点的
RGB。
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ScreenDemo {
public static File generateSnapshot() {
//File snapshotFile = new File("D:/" + System.currentTimeMillis() + ".jpg");
File snapshotFile = new File("D:/snapshot.jpg");
int width = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int height = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
try {
Robot robot;
robot = new Robot();
BufferedImage image = robot.createScreenCapture(new Rectangle(width, height));
ImageIO.write(image, "jpg", snapshotFile);
} catch (Exception e) {
e.printStackTrace();
}
return snapshotFile;
}
/**
* 取得图像上指定位置像素的 rgb 颜色分量。
*
* @param image 源图像。
* @param x 图像上指定像素位置的 x 坐标。
* @param y 图像上指定像素位置的 y 坐标。
* @return 返回包含 rgb 颜色分量值的数组。元素 index 由小到大分别对应 r,g,b。
*/
public static int[] getRGB(BufferedImage image, int x, int y) {
int[] rgb = null;
if (image != null && x < image.getWidth() && y < image.getHeight()) {
rgb = new int[3];
int pixel = image.getRGB(x, y);
rgb[0] = (pixel & 0xff0000) >> 16;
rgb[1] = (pixel & 0xff00) >> 8;
rgb[2] = (pixel & 0xff);
}
return rgb;
}
/**
* 将RGB转换为16进制Hex
*
* @param r red颜色分量
* @param g green颜色分量
* @param b blue颜色分量
* @return
*/
public static String toHex(int r, int g, int b) {
return "#" + toHexValue(r) + toHexValue(g) + toHexValue(b);
}
private static String toHexValue(int number) {
StringBuilder builder = new StringBuilder(Integer.toHexString(number & 0xff));
while (builder.length() < 2) {
builder.append("0");
}
return builder.toString().toUpperCase();
}
public static void printPointRGB(int x, int y) {
try {
BufferedImage bi = ImageIO.read(new File("D:/snapshot.jpg"));
int[] rgb = getRGB(bi, x, y);
Color color = new Color(rgb[0], rgb[1], rgb[2]);
System.out.println("red = " + color.getRed());
System.out.println("green = " + color.getGreen());
System.out.println("blue = " + color.getBlue());
System.out.println("hex = " + toHex(color.getRed(), color.getGreen(), color.getBlue()));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
generateSnapshot();
printPointRGB(100, 100);
}
}
posted @
2015-02-22 22:12 marchalex 阅读(1950) |
评论 (0) |
编辑 收藏
Java JDK1.4 的Robot对象可以完成对"屏幕"像素的拷贝,完成屏幕图像截取操作。Java应用程序中可以直接调用此对象,完成对特定应用程序的屏幕截取。
在Java JDK1.4 中提供的"机器人"Robot类用于产生与本地操作系统有关的底层输入、测试应用程序运行或自动控制应用程序运行。Robot类提供了一个方法:createScreenCapture(..),可以直接将全屏幕或某个屏幕区域的像素拷贝到一个BufferedImage对象中,我们只需要将该对象写入到一个图像文件之中,就完成了屏幕到图像的拷贝过程。
ScreenDemo类的generateSnapshot()方法用于实现对当前屏幕的截取。
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class ScreenDemo {
public static File generateSnapshot() {
File snapshotFile = new File("D:/" + System.currentTimeMillis() + ".jpg");
int width = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int height = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
try {
Robot robot;
robot = new Robot();
BufferedImage image = robot.createScreenCapture(new Rectangle(width, height));
ImageIO.write(image, "jpg", snapshotFile);
} catch (Exception e) {
e.printStackTrace();
}
return snapshotFile;
}
public static void main(String[] args) {
generateSnapshot();
}
}
posted @
2015-02-22 21:52 marchalex 阅读(260) |
评论 (0) |
编辑 收藏
Java SDK 1.3以后实现了Robot类。此类用于为测试自动化、自运行演示程序和其他需要控制鼠标和键盘的应用程序生成本机系统输入事件。Robot 的主要目的是便于 Java 平台实现自动测试。
使用该类生成输入事件与将事件发送到 AWT 事件队列或 AWT 组件的区别在于:事件是在平台的本机输入队列中生成的。例如,Robot.mouseMove 将实际移动鼠标光标,而不是只生成鼠标移动事件。
Robot中主要的鼠标和键盘控制方法有:
void keyPress(int keycode) 按下给定的键。
void keyRelease(int keycode) 释放给定的键。
void mouseMove(int x, int y) 将鼠标指针移动到给定屏幕坐标。
void mousePress(int buttons) 按下一个或多个鼠标按钮。
void mouseRelease(int buttons) 释放一个或多个鼠标按钮。
void mouseWheel(int wheelAmt) 在配有滚轮的鼠标上旋转滚轮。
下面是一个简单的示例
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
public class KeyController implements Runnable {
private Dimension dim;
private Robot robot;
private volatile boolean stop = false;
public KeyController() {
dim = Toolkit.getDefaultToolkit().getScreenSize();
System.out.println("computer imformation:\n" + "width:"+dim.width+"\theight:"+dim.height);
try {
robot = new Robot();
} catch (AWTException ex) {
ex.printStackTrace();
}
}
public void run() {
while(!stop) {
robot.mousePress(InputEvent.BUTTON1_MASK);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void stop() {
stop = true;
}
public static void main(String[] args) {
MouseController kc = new MouseController();
Thread kcThread = new Thread(kc);
System.out.println("Key Controller start");
kcThread.start();
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
kc.stop();
System.out.println("Mouse Controller stoped");
}
}
posted @
2015-02-21 23:09 marchalex 阅读(400) |
评论 (0) |
编辑 收藏
FileCreate类的createFile方法用于创建一个新文件。
file.mkdirs()方法可用于地柜的创建目录。
main方法用于测试。
import java.io.File;
import java.io.IOException;
public class FileCreate {
public static void createFile(String path, String filename) throws Exception {
File file = new File(path);
if(!file.exists()) {
file.mkdirs();
}
file = new File(path, filename);
if(!file.exists()) {
file.createNewFile();
}
}
public static void main(String[] args) throws Exception {
createFile("D:\\test", "hello.txt");
}
}
posted @
2015-02-13 14:38 marchalex 阅读(108) |
评论 (0) |
编辑 收藏
目前做到能分析POJ和HDU的代码。ZOJ的话因为他存储用户的方式是一个数字序列,而不是用户的id,所以暂时没有想到解决方案。
这里用到了之前提到的获取网页源代码的
URLAnalysis类。
getPOJSolved方法用于获得POJ上的解题数;
getHDUSolved方法用于获得HDU上的解题数;
names数组存放感兴趣的用户。
代码如下:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class OnlineJudgeFinder {
private static String[] names = {"watashi", "hanfei19910905", "marchalex"};
public static String getPOJSolved(String userId) throws Exception {
String urlString = "http://poj.org/userstatus?user_id=" + userId;
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line = null;
for(int i=0;i<10;i++)
line = reader.readLine();
int len = line.length();
int i , cnt = 0;
for(i=0;i<len;i++) {
if(line.charAt(i) == '>') {
cnt ++;
if(cnt == 2)
break;
}
}
i ++;
String num = "";
while(i < len && line.charAt(i) >= '0' && line.charAt(i) <= '9') {
num += line.charAt(i);
i ++;
}
return num;
}
public static String getHDUSolved(String userId) throws Exception {
String urlString = "http://acm.hdu.edu.cn/userstatus.php?user=" + userId;
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line = null;
for(int i=0;i<105;i++)
line = reader.readLine();
int len = line.length();
int i , cnt = 0;
for(i=0;i<len;i++) {
if(line.charAt(i) == '>') {
cnt ++;
if(cnt == 4)
break;
}
}
i ++;
String num = "";
while(i < len && line.charAt(i) >= '0' && line.charAt(i) <= '9') {
num += line.charAt(i);
i ++;
}
return num;
}
public static void getResult() throws Exception {
int n = names.length;
for(int i=0;i<n;i++) {
String name = names[i];
System.out.println(name + " has solved ");
System.out.println("\t" + getPOJSolved(name) + " problem(s) in POJ");
System.out.println("\t" + getHDUSolved(name) + " problem(s) in HDU");
}
}
public static void main(String[] args) throws Exception {
getResult();
}
}
效果如下:
watashi has solved
32 problem(s) in POJ
7 problem(s) in HDU
hanfei19910905 has solved
131 problem(s) in POJ
212 problem(s) in HDU
marchalex has solved
1 problem(s) in POJ
15 problem(s) in HDU
posted @
2015-02-13 13:30 marchalex 阅读(230) |
评论 (0) |
编辑 收藏