一例讲述lang,util,text包50种高级用法
程序员文章站
2022-03-02 21:36:38
...
对于我也是从新人成长而来的,深知刚毕业的新手对技术的追求和渴望。对于没有项目经验的毕业生来说,往往都会学习庞大的项目想快速提高自己。工作四五年我才明白基础才是王道,什么架构模式只有基础知识扎实了一切都迎刃而解。
接下来我为大家做了一个例子,把基础中的一些高级或者偏僻的方法都用上去了,以扩大新手对基础知识的理解。目我的总结还只有我设想的一部分(没有规范注解),后面我会慢慢的更新。
由于排版不方便我就有图片显示内容,可以放大图片看(为了排版,命名没有按规范来)。
企业级项目实战(带源码)地址:http://zz563143188.iteye.com/blog/1825168
收集五年的开发资料下载地址: http://pan.baidu.com/share/home?uk=4076915866&view=share
package com.j2se.base; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.math.BigDecimal; import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Properties; import java.util.Random; import java.util.Scanner; import java.util.Set; import java.util.Stack; import java.util.StringTokenizer; import java.util.TreeMap; import java.util.TreeSet; import java.util.Vector; import java.util.Map.Entry; /* * Title: 演示java基础操作类 * Description: XXXX XXXXXX 3.0 * Copyright: Copyright (c) 2003 * Company:XXXX有限公司 * * * @version 1.0 创建时间 2013-04-14 * @author 张林 563143188@qq.com * @since JDK1.3 * * <p> * 语言和结果没有严格参照java命名规范来 * <p> * <pre> * <blockquote> * public void show() * { * System.out.println(new Data()); * } * </blockquote> * </pre> * <ol> * <li>java基础知识讲解 * <li>java知识深入 * <li>文件多线程、网络放在下一篇写 * </ol> * * */ public class JavadocDemo { public enum OperatorType { all, mathOperator, bigMathOperator, bitOperator, listOperator, systemOperator, stringOperator, md5Operator } public static int rsCount = 0; // 记录递归的次数,放在接口里面 /* * @param a 传值 * * @return 执行的状态 * * @exception 没有异常抛出或者有 * * @link {@link com.j2se.base.JavadocDemo#mathOperator} * * @see java.lang.math */ public static boolean mathOperator() { rsCount = rsCount + 1; Random rnd = new Random();// 产生0到1之间的随机数 int intRnd = (new Random()).nextInt(Integer.MAX_VALUE % 1000);// 等同于这个rnd.nextInt(10); // 整形的要在括号里面给种子 double dblRnd = rnd.nextLong() * intRnd;// long, float // double获得随机数都是在外围*一个常数 pln("第" + rsCount + "次递归的 随机值:" + intRnd); // 递归是先释放最外层的然后再释放里面层 boolean isSuccess = (intRnd < 500) ? mathOperator() : true; // 三元表达式递归 // ,右边一定要返回值 if (isSuccess) { // 分割用正则表达式 char chrArr[] = itbi(intRnd).toCharArray();// 将整形转为二进制再给字符数组 StringBuffer strBin = new StringBuffer("二进制码:"); for (char chrTemp : chrArr) { strBin.append(chrTemp + ","); } pln(strBin.toString()); // StringTolen将,拆分为空格,也可以用split函数 StringTokenizer stoke = new StringTokenizer(strBin.toString(), ","); List<String> lisStoke = new ArrayList<String>(); while (stoke.hasMoreElements()) // 判断是否还有元素 { // nextToken() 返回字符串,nextElement返回 对象 lisStoke.add(stoke.nextElement().toString()); } ListIterator<String> itStoke = lisStoke.listIterator(); while (itStoke.hasNext()) { pln(itStoke.next().toString() + " "); } } return isSuccess; } public static void bitOperator() { int intNum = 124 % (-846 % 1000); // 负数求模是 (1000-864) 求法 7 -2 ≡ 7 + 10 // (mod 12) float fltNum = 124.10f; do { // 正数求反码是加负号还减1,如果是负数求反码是绝对值-1 pln(" 整数后一位小数保留一位 127.0f%3=" + (127.0f % 3) + " 有两位小数保留浮点位精度:" + fltNum + "%3=" + (fltNum % 3)); pln("正数的原码、反码、补码都是一致的"); pln(intNum + " 的原码值:" + String.format("%025d", 0) + itbi(intNum)); pln(intNum + " 的反码值:" + String.format("%025d", 0) + itbi(intNum)); pln(intNum + " 的补码值:" + String.format("%025d", 0) + itbi(intNum)); pln("负数的原码最高位为1、反码(在其原码的基础上, 符号位不变,其余各个位取反)、\n" + "补码(在其原码的基础上, 符号位不变, 其余各位取反, 最低位+1)"); pln((-intNum) + " 的原码值:1" + String.format("%024d", 0) + itbi(intNum)); pln((~intNum + 1) + " 的反码值:" + itbi((~intNum) + 1)); pln((~intNum + 1) + " 的补码值:" + itbi((~intNum) + 2)); pln("位移的运算 1.左移后,低位会被自动补零(0) 2.右移如果原值是正数," + "则高位补上0;如果原值是负数,高位补1。"); pln(intNum + "位移操作前的二进制码是 " + itbi(intNum)); pln(intNum + "位移操作前的八进制码是 " + Integer.toOctalString(intNum)); pln(intNum + "位移操作前十六进制码是 " + Integer.toHexString(intNum)); pln(intNum + "位移操作前的二进制码是 " + itbi(intNum)); pln(intNum + ">>有符号右移一位" + (intNum >> 1) + " 二进制码 " + itbi(intNum >> 1)); pln(intNum + ">>有符号左移一位" + (intNum << 1) + " 二进制码 " + itbi(intNum << 1)); pln("八进制174转十进制是:" + Integer.valueOf("174", 8) + " 十六进制7C转十进制是:" + Integer.valueOf("7C", 16)); pln("采用0补充,意思就是说,无论是正号还是负号,都在高位补0"); pln(intNum + ">>>无符号右移一位" + (intNum >>> 1) + " 二进制码 " + itbi(intNum >>> 1)); } while (false); } /* * list操作 */ public static void listOperator() { // 通过list接口向下扩展类 Class< List> clst = List. class; // 上界 Class<? extends List> subList = LinkedList.class .asSubclass(clst); // Class.forName("java.lang.LinkedList").asSubclass( clist) // .newInstance(); // 这样加载一个对象 Array ar; // 类提供了动态创建和访问 Java 数组的方法 java.lang.relect Arrays ars; // 该类用来操作数组(比如排序和搜索)的各种方法。允许将数组作为列表来查看静态工厂。 List<?> listVec = new Vector(); // 用ArrayList代替Vector。Vector是线程安全的 // 重量级,占据更多的系统开销 // Stack它是从Vector继承而来,对于一个栈来说,它只能是最后放进去的元素,要先出来, // 但是它继承自Vector,而Vector中有一个方法叫做elementAt( int index), // 而不能说是通过这个索引index去任意的获得一个元素。结果它就有了这个奇怪的特性。 Vector<?> st = new Stack(); List<?> lstArr = new ArrayList();// 非线程安全的数组 查询效率高,增删效率低 轻量级 List<?> lstLink = new LinkedList(); // 非线程安全 用LinkedList代替Stack。查询效率低,增删效率高 Iterator<?> litIt = st.iterator(); // Iterator 只有向下移位方法 // ListIterator有hasPrevious()和previous()方法,实现逆向(顺序向前)遍历,修改set()方法可以。 ListIterator<?> litLit = lstLink.listIterator(); Set<?> hSet = new HashSet(); // HashSet是通过HashMap实现的 // 只能放入一个null,两者中的值都不能重复 // hashCode和equal()是HashMap用的 // TreeSet是通过TreeMap实现的 ,有排序的功能,需要排序用Comparator为键值进行大小比较定位 Set<?> tSet = new TreeSet(); // 可以排序的 不允许放入null值 // set只有Iterator没有listIterator Iterator<?> setIt = hSet.iterator(); //--- Map<?, ?> tMap = new TreeMap(); // 默认是按升序排序 不允许放入null值 // HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null Map<?, ?> hMap = new HashMap(); // 用HashMap非线程安全代替 Hashtable。 // HashTable使用Enumeration,HashMap使用Iterator Map<?, ?> htMap = new Hashtable(); // Hashtable 是线程安全的 key和value都不可以不能为空 // Map没有Iterator和listIterator功能,只有Map.Entry方法迭代 Iterator<?> litMap = tMap.entrySet().iterator(); Iterator<?> litHMap = hMap.entrySet().iterator(); Iterator<?> litHTMap = htMap.entrySet().iterator(); Map.Entry<Object, Object> mapIt = (Entry<Object, Object>) tMap .entrySet() ; } // 高精度运算,浮点等等 指数 货币转换 科学计算法 内存交互 模拟矩阵 解方程 /* * java.math是一个包,执行任意精度整数算法 (BigInteger)和任意精度小数算法 (BigDecimal)专业数学运算. * java.lang.Math是一个类,类包含基本的数字操作,如指数、对数、平方根和三角函数。货币 */ public static void bigMathOperator() { // ceil向上取整,返回double floor向下取整,返回double rint 返回近似数 // round 是对其加0.5四舍五入求整 // int number = 10 + (int) (Math.random() * 10); 如果要得到一个(10, 20]之间的随机整数: double maxValue = Math.max(Math.floor(Math.ceil(Math.tan(Math.sin(50) / Math.cos(30))) + Math.rint(Math.round(Math.PI) + Math.E)), (10 + (int) (Math .random() * 10))); double expValue = Math.pow(Math.E, 2);// Math.E的二次方 // 指数用对数表示 Math.exp求e的任意次方 log_8(2)对数表示为 Math.log(8)/Math.log(2) pln("exp(Math.PI)=" + Math.exp(Math.PI) + " Math.pow(2,Math.PI*log_2(E))=" + Math.pow(2, Math.PI * (Math.log(Math.E) / Math.log(2)))); /* * java.math.BigInteger(大整数) java.math.BigDecimal(大浮点数) * BigDecimal.setScale()方法用于格式化小数点 setScale(1)表示保留一位小数,默认用四舍五入方式 * setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3 * setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4 * setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4 * setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍 */ BigDecimal bdValue = new BigDecimal(Double.MAX_VALUE); pln("直接删除三位以后的小数位:" + (new BigDecimal(Math.PI)).setScale(3, BigDecimal.ROUND_DOWN)); pln("打印double的全部值并加两个小位数:" + bdValue.setScale(2).toEngineeringString()); pln("(大精度运算) Math.PI*Math.E = " + mul(Math.PI, Math.E)); pln("(大精度运算) Double.MAX_VALUE/Float.MAX_VALUE = " + new BigDecimal(div(Double.MAX_VALUE, Float.MAX_VALUE, 3))); // DecimalFormat 与科学计算法 E20后面表示的10的20次方 如果是E-20则表是是 10的(1/N)次方 pln("分解科学计算法表示的:3.1415E-20的值=" + new BigDecimal("3.1415E-20").toPlainString()); pln("分解科学计算法表示的:3.1415E20 的值=" + new BigDecimal("3.1415E20").toPlainString()); // 分解科学计算法表示的:3.1415E-20的值=0.000000000000000000031415 // 分解科学计算法表示的:3.1415E20 的值=314150000000000000000 } /** * 提供精确的乘法运算。 * * @param v1 * 被乘数 * @param v2 * 乘数 * @return 两个参数的积 */ public static double mul(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.multiply(b2).doubleValue(); } /** * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。 * * @param v1 * 被除数 * @param v2 * 除数 * @param scale * 表示表示需要精确到小数点以后几位。 * @return 两个参数的商 */ public static double div(double v1, double v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } // Thread t = new ShutdownHookThread ( "Here I am !!!" ); // Runtime.getRuntime().addShutdownHook ( t ); // System.out.println ( "Now shut me down …"); public static void md5Operator() { String str = ""; // 加密后,然后解密 MessageDigest md; try { md = MessageDigest.getInstance("MD5"); String plainText = "我是有钱人,你们信不信!"; md.update(plainText.getBytes()); byte b[] = md.digest(); int i; StringBuffer buf = new StringBuffer(""); for (int offset = 0; offset < b.length; offset++) { i = b[offset]; if (i < 0) i += 256; if (i < 16) buf.append("0"); buf.append(Integer.toHexString(i)); } str = buf.toString(); pln("加密前的信息:" + plainText); System.out.println("32位的加密: " + buf.toString());// 32位的加密 System.out.println("16位的加密: " + buf.toString().substring(8, 24));// } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void stringOperator() { Charset dCharset = java.nio.charset.Charset.defaultCharset(); pln("当前环境编码:" + dCharset.name()); StringBuilder sber = new StringBuilder("StringBuilder是非线程安全的,"); sber.append("StringBuffer是线程安全的"); sber.append("两种用法差不多,很多方法与string一样"); sber.append("如果不考虑线程安全用StringBuiler "); CharSequence chrSeq = sber.subSequence(60, sber.length() - 1); pln(chrSeq.toString()); String strTemp = "53 48 07 03 0B 43 50 C6 00 00 67";// 一条机器执行状态返回指令 String testResult = ((strTemp.indexOf("C6") >= 0) ? true : false) ? "执行成功" : "执行失败"; String isOkCode = strTemp.split(" ")[(strTemp.lastIndexOf("C6") / 3) % 21]; pln("这次测试".concat(testResult.intern()) + " 正确代码:" + isOkCode); pln("仪器型号:" + strTemp.substring(strTemp.indexOf("53"), strTemp .indexOf("48"))); pln("指令帧长:" + strTemp.charAt(7)); pln(" 指令效验合:" + strTemp.substring(strTemp.lastIndexOf("00") + 3)); } // secrurity rmi net beans 合用一个例子 // Preferences pf = Preferences.systemRoot(); pln(pf.absolutePath());// public static void systemOperator() { String temp = "自1970年1月1日到现在的毫秒数:"; pln(temp + System.currentTimeMillis()); Properties sysPorp = System.getProperties(); // 获得系统属性 Set<Entry<Object, Object>> sysSet = sysPorp.entrySet(); // 1.用Set的entry方式取信息 // 2.用map的方式读取 通过下界通配符定义 key值 Map<? super String, Object> sysMap = new HashMap<String, Object>(); Iterator<Entry<Object, Object>> sysIt = sysSet.iterator();// 同理:sysMap.entrySet().iterator(); for (; sysIt.hasNext();) { Map.Entry<Object, Object> sysEt = (Entry<Object, Object>) sysIt .next(); sysMap.put(sysEt.getKey().toString(), sysEt.getValue()); } // 2.用map的方式读取 通过上界通配符定义 Enumeration<? extends Object> sysEm = sysPorp.propertyNames(); while (sysEm.hasMoreElements()) { Object obj = sysEm.nextElement(); // pln(obj + "=" + sysPorp.get(obj));// 通过枚举打印所有的系统参数 } // new Properties(System.getProperties()).list(System.out); 3.用输出流的方法 // scanner一般都是扫描控制台或者扫描文件 Scanner scer = new Scanner(System.in); do { System.out.println("请输入命令是否要继续下面的操作(1/0):"); Scanner scer1 = new Scanner("张林,好人嘛,你只能在这输入1才能继续下面的操作"); scer1.useDelimiter(","); while (scer1.hasNext()) pln(scer1.next()); String line = scer.nextLine(); if (line.equals("1")) break; pln(">>>" + line); } while (true); try { Thread.currentThread(); Thread.sleep((new Random()).nextInt(1000)); try { String[] cmd = { "cmd", "/C", "copy exe1 exe2" }; Process proc = Runtime.getRuntime().exec(cmd); // int exitVal = proc.waitFor(); // System.out.println("Process exitValue: " + exitVal); // Runtime.getRuntime().exit(0); 这个是直接结束jvm,不会执行finally } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } finally { // Calendar.getInstance() 是静态方法,可以直接调用,不用new pln(temp + Calendar.getInstance().getTimeInMillis()); Runtime rt = Runtime.getRuntime(); pln("系统内存大小清理前:" + rt.totalMemory() + " 空闲内存大小清理前:" + rt.freeMemory()); rt.gc(); // 手工垃圾清理 pln("系统内存大小清理后:" + rt.totalMemory() + " 空闲内存大小清理后:" + rt.freeMemory()); } } public static void ortherOperator() { int x = 0; int y = 0; int z = 0; char temp = '好';// java中的 char可以存一个汉字,因为默认是 utf-8的 if ((z == 2) & (++x > 0)) { // goto 是关键字但不能使用 } pln(x + " 通 & 条件比较即使 z==2条件不成立, (++x)同样会执行,所以当前x=1"); if ((z == 2) && (++y > 0)) { } pln(y + " 通 & 条件比较即使 z==2条件不成立, (++y)不会执行,所以当前y=0"); } public static void main(String args[]) { // ortherOperator(); switchOperator(OperatorType.md5Operator); } // 通过二进制位置确定操作那几个方法 ,与或关系来解决 public static void switchOperator(OperatorType opt) { switch (opt) { // 条件只是整型或者字符型 枚举可以,浮点型不行 case all:// 可以带表达式,但不能是变量 break; case mathOperator: mathOperator(); break; case bitOperator: bitOperator(); break; case listOperator: listOperator(); break; case systemOperator: systemOperator(); break; case stringOperator: stringOperator(); break; case md5Operator: md5Operator(); break; case bigMathOperator: bigMathOperator(); break; default: System.out.println("没有该类型的操作"); } } public static void pln(String str) { System.out.println(str); } public static String itbi(int x) { return Integer.toBinaryString(x); } /* * @deprecated(non-Javadoc) * * @see java.lang.Object#finalize() */ protected void finalize() { System.out.println("清理系统垃圾"); } } /* * 一个例子说明了类,抽象类,匿名类,接口,线程简单用法 * * **/ abstract class Test { static { System.out.println("下面只是一些简单的测试,欢迎学习"); } // 申明一个函数方法,不实现 public abstract void callAnonymousMethod(); public void finalize() { System.out.println("销毁所有的对象,这是在最后调用"); } } interface MainTest { // 因为java的char类型是2个字节,因此可以保存一个汉字 public final static char isDemo = '是'; // 接口的常量没有标识,则默认是 public final static String tName = "mainTest"; void printNum(); // 方法默认是public abstract } class mainTestImpl extends Test { // 可以延伸一个抽象类 public static class innerTest { // 申明一个内部类 public void tShowInfo(MainTest s) { // 传一个接口对象过来 s.printNum(); // 调用一下mainTest接口里方法,不实现 } } /* * 任何线程一般具有五种状态,即创建、就绪、运行、阻塞、终止 线程 调用stop()方法时或run()方法执行结束后,线程即处于死亡状态。 * 处于死亡状态的线程不具有继续运行的能力。 */ public static void main(String[] args) { // testThread t = new testThread(); // t.start(); // start是启动一个线程由程序来调用run方法 // run 刚是运行一个方法,等结束以后再执行后面的代码,不能达到多线程目的 threadImp tl = new threadImp(); new Thread(tl).start(); // 交给程序调用线程 Thread 也实现了ruunable Thread t = new Thread(tl); new mainTestImpl().callAnonymousMethod(); new mainTestImpl().finalize(); // 始终在线程结束后调用 } // 实现抽象类中的方法 public void callAnonymousMethod() { // 通过匿名函数现mainTest接口里面的printNum方法,不申明直接new直是匿名调用 new innerTest().tShowInfo(new MainTest() { public void printNum() { for (int i = 0; i < 30; i++) { // tName是接口中的常量,直接引用 System.out.println(tName + " " + Thread.currentThread().getName() + " = " + i); } } }); } } // 通过类继承必须有run方法,因为start启动线程后由程序调用run方法 // Thread同样实现了Runnable接口 class testThread extends Thread { // 后面的类不能用public 方法 public void run() { for (int i = 0; i < 30; i++) { System.out.println("testThread=" + Thread.currentThread().getName() + " " + i); } } } /* * JAVA程序只允许单一继承,即一个子类只能有一个父类,所以在 Java中如果一个 类继承了某一个类, 同时又想采用多线程技术的时,就不能用 * Thread类产生线程,因为 Java不允许多继承, 这时就要用 Runnable接口来创建线程了。 */ class threadImp implements Runnable { // 线程的几个状态,判断属性,计数次数,同步方法 public void run() { synchronized (this) { for (int i = 0; i < 30; i++) { System.out.println("runnable=" + Thread.currentThread().getName() + " " + i); } } } public synchronized void sale() // 同步方法,可以代码块也可以方法体 { } } /* * 反射的高级用法,通过参数调用 方法 * */ class DoImpDataBean { private static final long serialVersionUID = 1L; public Map sqlserver; public Map oracle; public Map db2; public Map sybase; public Map informix; public Map mysql; public Map getDbInfo(String mname) { DoImpDataBean dobean = new DoImpDataBean(); Class bean = DoImpDataBean.class; Map<String, String> map = new HashMap<String, String>(); try { Method md = bean.getMethod(mname, null); map = (Map) md.invoke(dobean, null); } catch (Exception e) { System.out.println("反射数据类型错误!"); } return map; } public Map getSqlserver() { Map<String, String[]> map = new HashMap<String, String[]>(); String[] columnTypeEn = new String[] { "bigint", "binary", "bit", "char", "datetime", "decimal", "float", "image", "int", "money", "nchar", "ntext", "numeric", "nvarchar", "real", "smalldatetime", "smallint", "smallmoney", "sql_variant", "sysname", "text", "timestamp", "tinyint", "uniqueidentifier", "varbinary", "varchar", "xml" }; String[] columnTypeCn = new String[] { "小数字", "二进制", "bit", "单字符", "日期", "decimal", "小数位", "图片", "数字", "货币", "宽字符", "宽文本", "numeric", "宽字符", "real", "短日期", "短整形", "短货币", "sql_variant", "sysname", "文本", "timestamp", "tinyint", "uniqueidentifier", "varbinary", "字符串", "xml" }; String[] charFiled = new String[] { "", "'", "'", "'", "'",// "", "", "'", "", "'", "'", "'", "", "'",// "'", "'", "", "'", "'", "'", "'",// "'", "", "'", "'", "'", // "'", };// map.put("columnTypeEn", columnTypeEn); map.put("columnTypeCn", columnTypeCn); map.put("charFiled", charFiled); return map; } public Map getOracle() { return oracle; } public Map getDb2() { return db2; } public Map getSybase() { return sybase; } public Map getInformix() { return informix; } public Map getMysql() { return mysql; } public static void main(String args []) { //通过伟参数调用DoImpDataBean类的getSqlserver方法 Map map= new DoImpDataBean().getDbInfo("getSqlserver"); Iterator<Map.Entry<Object, Object>> itMap=map.entrySet().iterator(); while(itMap.hasNext()) { Map.Entry<Object, Object> mapEn=(Map.Entry<Object, Object>)itMap.next(); String [] column=(String []) map.get(mapEn.getKey()); for (int i=0;i<column.length;i++) { System.out.println("Key:"+mapEn.getKey()+" Value :"+column[i]); } } } } /** * * * * 系统属性操作 * 取注册表 * * * */ class SystemInfo { /* Windows security masks */ private final static int KEY_QUERY_VALUE = 1; /* Constants used to interpret returns of native functions */ private final static int NATIVE_HANDLE = 0; private final static int ERROR_CODE = 1; /* Windows error codes. */ private final static int ERROR_SUCCESS = 0; private static String absolutePath() { return "/"; } private static byte[] windowsAbsolutePath(byte[] WINDOWS_ROOT_PATH) { ByteArrayOutputStream bstream = new ByteArrayOutputStream(); bstream.write(WINDOWS_ROOT_PATH, 0, WINDOWS_ROOT_PATH.length - 1); StringTokenizer tokenizer = new StringTokenizer(absolutePath(), "/"); while (tokenizer.hasMoreTokens()) { bstream.write((byte) '\\'); String nextName = tokenizer.nextToken(); byte[] windowsNextName = toWindowsName(nextName); bstream.write(windowsNextName, 0, windowsNextName.length - 1); } bstream.write(0); return bstream.toByteArray(); } public static String getValue(int hkey, byte[] WINDOWS_ROOT_PATH, String key) throws Exception { Class theClass = Class.forName("java.util.prefs.WindowsPreferences"); int[] result = openKey1(hkey, windowsAbsolutePath(WINDOWS_ROOT_PATH), KEY_QUERY_VALUE); if (result[ERROR_CODE] != ERROR_SUCCESS) { throw new Exception("Path not found!"); } int nativeHandle = result[NATIVE_HANDLE]; Method m = theClass.getDeclaredMethod("WindowsRegQueryValueEx", new Class[] { int.class, byte[].class }); m.setAccessible(true); byte[] windowsName = toWindowsName(key); Object value = m.invoke(null, new Object[] { new Integer(nativeHandle), windowsName }); WindowsRegCloseKey(nativeHandle); if (value == null) { throw new Exception("Path found. Key not found."); } byte[] origBuffer = (byte[]) value; byte[] destBuffer = new byte[origBuffer.length - 1]; System.arraycopy(origBuffer, 0, destBuffer, 0, origBuffer.length - 1); return new String(destBuffer); } public static int WindowsRegCloseKey(int nativeHandle) throws Exception { Class theClass = Class.forName("java.util.prefs.WindowsPreferences"); Method m = theClass.getDeclaredMethod("WindowsRegCloseKey", new Class[] { int.class }); m.setAccessible(true); Object ret = m.invoke(null, new Object[] { new Integer(nativeHandle) }); return ((Integer) ret).intValue(); } private static byte[] toWindowsName(String javaName) { StringBuffer windowsName = new StringBuffer(); for (int i = 0; i < javaName.length(); i++) { char ch = javaName.charAt(i); if ((ch < 0x0020) || (ch > 0x007f)) { throw new RuntimeException( "Unable to convert to Windows name"); } if (ch == '\\') { windowsName.append("//"); } else if (ch == '/') { windowsName.append('\\'); } else if ((ch >= 'A') && (ch <= 'Z')) { windowsName.append("/" + ch); } else { windowsName.append(ch); } } return stringToByteArray(windowsName.toString()); } public static int[] openKey1(int hkey, byte[] windowsAbsolutePath, int securityMask) throws Exception { Class<?> theClass = Class.forName("java.util.prefs.WindowsPreferences"); Method m = theClass.getDeclaredMethod("WindowsRegOpenKey", new Class[] { int.class, byte[].class, int.class }); m.setAccessible(true); Object ret = m.invoke(null, new Object[] { new Integer(hkey), windowsAbsolutePath, new Integer(securityMask) }); return (int[]) ret; } private static byte[] stringToByteArray(String str) { byte[] result = new byte[str.length() + 1]; for (int i = 0; i < str.length(); i++) { result[i] = (byte) str.charAt(i); } result[str.length()] = 0; return result; } }