Java lang,until,text包50种高级用法
转载:原文地址http://zz563143188.iteye.com/blog/1849952
1 package com.pbz.demo; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 import java.lang.reflect.Array; 6 import java.lang.reflect.Method; 7 import java.math.BigDecimal; 8 import java.nio.charset.Charset; 9 import java.security.MessageDigest; 10 import java.security.NoSuchAlgorithmException; 11 import java.util.ArrayList; 12 import java.util.Arrays; 13 import java.util.Calendar; 14 import java.util.Enumeration; 15 import java.util.HashMap; 16 import java.util.HashSet; 17 import java.util.Hashtable; 18 import java.util.Iterator; 19 import java.util.LinkedList; 20 import java.util.List; 21 import java.util.ListIterator; 22 import java.util.Map; 23 import java.util.Properties; 24 import java.util.Random; 25 import java.util.Scanner; 26 import java.util.Set; 27 import java.util.Stack; 28 import java.util.StringTokenizer; 29 import java.util.TreeMap; 30 import java.util.TreeSet; 31 import java.util.Vector; 32 import java.util.Map.Entry; 33 34 /* 不是故意卖弄而是展示各个知识点 35 * Title: XXXX DRIVER 3.0 36 *Description: XXXX DRIVER 3.0 37 *Copyright: Copyright (c) 2003 38 *Company:XXXX有限公司 39 *@deprecated 40 *@since JDK1.2 可以运行的环境 41 * 42 * html标签 http://www.w3school.com.cn/tags/tag_blockquote.asp 43 * @link标记 44 语法:{@link package.class#member label} 45 Label为链接文字。 46 package.class#member将被自动转换成指向package.class的member文件的URL。 47 * 48 * */ 49 /* 伪代码 * @docRoot @see @seriaData @serialField 50 * 这是我为大家演示的一个javadco的例子,目的是让你们一下就能熟悉javadoc 51 * <p> 52 * 这个<code>JavadocDemo</code>是一个基类,将实现接口和继承抽象类,会对一些极少的操作 53 * 属性和方法列举出来,主要是为了扫清知识死角 54 * <p> javadoc是支持html标记格式的, 55 * <pre><blockquote> 56 * public void show() 57 * { 58 * System.out.println(new Data()); 59 * } 60 * </blockquote> 61 * </pre> 62 * * <ol> 63 * <li> 64 * <li> 65 * </ol> 66 * 67 * 这里采用XX,详请 @see java.util.List#method 68 * 69 * @version 1.0 创建时间 2013-04-14 70 * @author 张林 563143188@qq.com 71 * @since JDK1.3 72 * 73 * */ 74 75 /* 76 * 注意javadoc 只能为public(公共)和protected(受保护)成员处理注释文档。 77 * “private”(私有)和“友好”(成员的注释会被忽略, 78 * 不要将<h1>或<hr>这样的标题当作嵌入HTML 使用,因为 79 javadoc 会插入自己的标题,我们给出的标题会与之冲撞。 80 所有类型的注释文档——类、变量和方法——都支持嵌入HTML。 81 * */ 82 83 /*文件多线程、网络放在下一篇写*/ 84 85 public class JavadocDemo { 86 public enum OperatorType { 87 all, mathOperator, bigMathOperator, bitOperator, listOperator, systemOperator, stringOperator, md5Operator 88 } 89 90 public static int rsCount = 0; // 记录递归的次数,放在接口里面 91 92 /* 93 * @param a 传值 94 * 95 * @return 执行的状态 96 * 97 * @exception 没有异常抛出或者有 98 */ 99 100 public static boolean mathOperator() { 101 rsCount = rsCount + 1; 102 103 Random rnd = new Random();// 产生0到1之间的随机数 104 105 int intRnd = (new Random()).nextInt(Integer.MAX_VALUE % 1000);// 等同于这个rnd.nextInt(10); 106 // 整形的要在括号里面给种子 107 double dblRnd = rnd.nextLong() * intRnd;// long, float 108 // double获得随机数都是在外围*一个常数 109 110 pln("第" + rsCount + "次递归的 随机值:" + intRnd); // 递归是先释放最外层的然后再释放里面层 111 112 boolean isSuccess = (intRnd < 500) ? mathOperator() : true; // 三元表达式递归 113 // ,右边一定要返回值 114 if (isSuccess) { 115 // 分割用正则表达式 116 char chrArr[] = itbi(intRnd).toCharArray();// 将整形转为二进制再给字符数组 117 StringBuffer strBin = new StringBuffer("二进制码:"); 118 119 for (char chrTemp : chrArr) { 120 strBin.append(chrTemp + ","); 121 } 122 pln(strBin.toString()); 123 // StringTolen将,拆分为空格,也可以用split函数 124 StringTokenizer stoke = new StringTokenizer(strBin.toString(), ","); 125 List<String> lisStoke = new ArrayList<String>(); 126 while (stoke.hasMoreElements()) // 判断是否还有元素 127 { 128 // nextToken() 返回字符串,nextElement返回 对象 129 lisStoke.add(stoke.nextElement().toString()); 130 } 131 132 ListIterator<String> itStoke = lisStoke.listIterator(); 133 while (itStoke.hasNext()) { 134 pln(itStoke.next().toString() + " "); 135 } 136 137 } 138 return isSuccess; 139 140 } 141 142 public static void bitOperator() { 143 int intNum = 124 % (-846 % 1000); // 负数求模是 (1000-864) 求法 7 -2 ≡ 7 + 10 144 // (mod 12) 145 float fltNum = 124.10f; 146 do { 147 // 正数求反码是加负号还减1,如果是负数求反码是绝对值-1 148 pln(" 整数后一位小数保留一位 127.0f%3=" + (127.0f % 3) + " 有两位小数保留浮点位精度:" 149 + fltNum + "%3=" + (fltNum % 3)); 150 pln("正数的原码、反码、补码都是一致的"); 151 pln(intNum + " 的原码值:" + String.format("%025d", 0) + itbi(intNum)); 152 pln(intNum + " 的反码值:" + String.format("%025d", 0) + itbi(intNum)); 153 pln(intNum + " 的补码值:" + String.format("%025d", 0) + itbi(intNum)); 154 pln("负数的原码最高位为1、反码(在其原码的基础上, 符号位不变,其余各个位取反)、\n" 155 + "补码(在其原码的基础上, 符号位不变, 其余各位取反, 最低位+1)"); 156 pln((-intNum) + " 的原码值:1" + String.format("%024d", 0) 157 + itbi(intNum)); 158 pln((~intNum + 1) + " 的反码值:" + itbi((~intNum) + 1)); 159 pln((~intNum + 1) + " 的补码值:" + itbi((~intNum) + 2)); 160 161 pln("位移的运算 1.左移后,低位会被自动补零(0) 2.右移如果原值是正数," 162 + "则高位补上0;如果原值是负数,高位补1。"); 163 164 pln(intNum + "位移操作前的二进制码是 " + itbi(intNum)); 165 pln(intNum + "位移操作前的八进制码是 " + Integer.toOctalString(intNum)); 166 pln(intNum + "位移操作前十六进制码是 " + Integer.toHexString(intNum)); 167 pln(intNum + "位移操作前的二进制码是 " + itbi(intNum)); 168 pln(intNum + ">>有符号右移一位" + (intNum >> 1) + " 二进制码 " 169 + itbi(intNum >> 1)); 170 pln(intNum + ">>有符号左移一位" + (intNum << 1) + " 二进制码 " 171 + itbi(intNum << 1)); 172 pln("八进制174转十进制是:" + Integer.valueOf("174", 8) + " 十六进制7C转十进制是:" 173 + Integer.valueOf("7C", 16)); 174 pln("采用0补充,意思就是说,无论是正号还是负号,都在高位补0"); 175 pln(intNum + ">>>无符号右移一位" + (intNum >>> 1) + " 二进制码 " 176 + itbi(intNum >>> 1)); 177 178 } while (false); 179 } 180 181 // 取到内存中的类,缓存,并修改后然后调用改变数据类型 动态代理 回调,递归,迭代 类加载器 182 // stack用法 list ,map的例子,数组 183 // 接口,反射类的方法做 访问权限 组合,继承 runtime ,system.getp 代理放到后面 匿名类 instance, 184 // 链表,递归,排序 多维数组 位疑惑权限, ,对象的比较 185 186 /* 187 * 如果我们看到了implements子句。正如我们看到的,Comparable类通常被定义为可以同自己比较的。 而且他们的子类 188 * 也可以同他们的父类比较。从另一个方面将,Enum实现了Comparable接口不是为了他本身, 而是为了他的子类 E。 treeMap stack 189 * hashTable 写一个自己排序的方向 数据逆向反转 190 * 191 * 大数据查询排序 请使用LinkedList来模拟一个队列(先进先出的特性)。拥有 放入对象的方法 void put(Object o)、 192 * 取出对象的方法Object get()、 判断队列当中是否为空的方法boolean isEmpty(); 193 * 并且,编写测试代码,验证你的队列是否正确。 Calendar 字符转换,转码 Expression 194 */ 195 196 public static void listOperator() { 197 // 通过list接口向下扩展类 198 Class<List> clst = List.class; 199 // 上界 200 Class<? extends List> subList = LinkedList.class.asSubclass(clst); 201 // Class.forName("java.lang.LinkedList").asSubclass(clist) 202 // .newInstance(); // 这样加载一个对象 203 204 Array ar; // 类提供了动态创建和访问 Java 数组的方法 java.lang.relect 205 Arrays ars;// 该类用来操作数组(比如排序和搜索)的各种方法。允许将数组作为列表来查看静态工厂。 206 List<?> listVec = new Vector(); //用ArrayList代替Vector。Vector是线程安全的 207 //Stack它是从Vector继承而来,对于一个栈来说,它只能是最后放进去的元素,要先出来, 208 //但是它继承自Vector,而Vector中有一个方法叫做elementAt(int index), 209 //而不能说是通过这个索引index去任意的获得一个元素。结果它就有了这个奇怪的特性。 210 Vector<?> st = new Stack(); 211 List<?> lstArr = new ArrayList();//非线程安全的数组 212 List<?> lstLink = new LinkedList(); //用LinkedList代替Stack。 213 214 215 Iterator<?> litIt = st.iterator();// Iterator 只有向下移位方法 216 // ListIterator有hasPrevious()和previous()方法,实现逆向(顺序向前)遍历,修改set()方法可以。 217 ListIterator litLit = lstLink.listIterator(); 218 219 Set<?> hSet = new HashSet(); //HashSet是通过HashMap实现的 hashCode和equal()是HashMap用的 220 //TreeSet是通过TreeMap实现的 ,有排序的功能,需要排序用Comparator为键值进行大小比较定位 221 Set<?> tSet = new TreeSet(); 222 // set只有Iterator没有listIterator 223 Iterator<?> setIt = hSet.iterator(); // 224 225 Map<?, ?> tMap = new TreeMap(); //默认是按升序排序 226 Map<?, ?> hMap = new HashMap();//用HashMap非线程安全代替Hashtable。 227 Map<?, ?> htMap = new Hashtable();//Hashtable是线程安全的 不能为空 228 229 // Map没有Iterator和listIterator功能,只有Map.Entry方法迭代 230 Iterator<?> litMap=tMap.entrySet().iterator(); 231 Iterator<?> litHMap=hMap.entrySet().iterator(); 232 Iterator<?> litHTMap=htMap.entrySet().iterator(); 233 234 Map.Entry<Object, Object> mapIt = (Entry<Object, Object>) tMap 235 .entrySet(); 236 237 } 238 239 // 高精度运算,浮点等等 指数 货币转换 科学计算法 内存交互 模拟矩阵 解方程 240 241 /* 242 * java.math是一个包,执行任意精度整数算法 (BigInteger)和任意精度小数算法 (BigDecimal)专业数学运算. 243 * java.lang.Math是一个类,类包含基本的数字操作,如指数、对数、平方根和三角函数。货币 244 */ 245 public static void bigMathOperator() { 246 // ceil向上取整,返回double floor向下取整,返回double rint 返回近似数 247 // round 是对其加0.5四舍五入求整 248 // int number = 10 + (int) (Math.random() * 10); 如果要得到一个(10, 20]之间的随机整数: 249 double maxValue = Math.max(Math.floor(Math.ceil(Math.tan(Math.sin(50) 250 / Math.cos(30))) 251 + Math.rint(Math.round(Math.PI) + Math.E)), (10 + (int) (Math 252 .random() * 10))); 253 double expValue = Math.pow(Math.E, 2);// Math.E的二次方 254 // 指数用对数表示 Math.exp求e的任意次方 log_8(2)对数表示为 Math.log(8)/Math.log(2) 255 pln("exp(Math.PI)=" + Math.exp(Math.PI) 256 + " Math.pow(2,Math.PI*log_2(E))=" 257 + Math.pow(2, Math.PI * (Math.log(Math.E) / Math.log(2)))); 258 259 /* 260 * java.math.BigInteger(大整数) java.math.BigDecimal(大浮点数) 261 * BigDecimal.setScale()方法用于格式化小数点 setScale(1)表示保留一位小数,默认用四舍五入方式 262 * setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3 263 * setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4 264 * setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4 265 * setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍 266 */ 267 BigDecimal bdValue = new BigDecimal(Double.MAX_VALUE); 268 pln("直接删除三位以后的小数位:" 269 + (new BigDecimal(Math.PI)).setScale(3, BigDecimal.ROUND_DOWN)); 270 pln("打印double的全部值并加两个小位数:" + bdValue.setScale(2).toEngineeringString()); 271 272 pln("(大精度运算) Math.PI*Math.E = " + mul(Math.PI, Math.E)); 273 pln("(大精度运算) Double.MAX_VALUE/Float.MAX_VALUE = " 274 + new BigDecimal(div(Double.MAX_VALUE, Float.MAX_VALUE, 3))); 275 276 // DecimalFormat 与科学计算法 E20后面表示的10的20次方 如果是E-20则表是是 10的(1/N)次方 277 278 pln("分解科学计算法表示的:3.1415E-20的值=" 279 + new BigDecimal("3.1415E-20").toPlainString()); 280 pln("分解科学计算法表示的:3.1415E20 的值=" 281 + new BigDecimal("3.1415E20").toPlainString()); 282 // 分解科学计算法表示的:3.1415E-20的值=0.000000000000000000031415 283 // 分解科学计算法表示的:3.1415E20 的值=314150000000000000000 284 } 285 286 /** 287 * 提供精确的乘法运算。 288 * 289 * @param v1 290 * 被乘数 291 * @param v2 292 * 乘数 293 * @return 两个参数的积 294 */ 295 296 public static double mul(double v1, double v2) { 297 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 298 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 299 return b1.multiply(b2).doubleValue(); 300 } 301 302 /** 303 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。 304 * 305 * @param v1 306 * 被除数 307 * @param v2 308 * 除数 309 * @param scale 310 * 表示表示需要精确到小数点以后几位。 311 * @return 两个参数的商 312 */ 313 314 public static double div(double v1, double v2, int scale) { 315 if (scale < 0) { 316 throw new IllegalArgumentException( 317 "The scale must be a positive integer or zero"); 318 } 319 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 320 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 321 return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); 322 } 323 324 // Thread t = new ShutdownHookThread ( "Here I am !!!" ); 325 326 // Runtime.getRuntime().addShutdownHook ( t ); 327 328 // System.out.println ( "Now shut me down …"); 329 public static void md5Operator() { 330 String str = ""; 331 // 加密后,然后解密 332 MessageDigest md; 333 try { 334 md = MessageDigest.getInstance("MD5"); 335 String plainText = "我是有钱人,你们信不信!"; 336 md.update(plainText.getBytes()); 337 byte b[] = md.digest(); 338 339 int i; 340 341 StringBuffer buf = new StringBuffer(""); 342 for (int offset = 0; offset < b.length; offset++) { 343 i = b[offset]; 344 if (i < 0) 345 i += 256; 346 if (i < 16) 347 buf.append("0"); 348 buf.append(Integer.toHexString(i)); 349 } 350 str = buf.toString(); 351 pln("加密前的信息:" + plainText); 352 System.out.println("32位的加密: " + buf.toString());// 32位的加密 353 System.out.println("16位的加密: " + buf.toString().substring(8, 24));// 354 } catch (NoSuchAlgorithmException e) { 355 // TODO Auto-generated catch block 356 e.printStackTrace(); 357 358 } 359 360 } 361 362 public static void stringOperator() { 363 Charset dCharset = java.nio.charset.Charset.defaultCharset(); 364 pln("当前环境编码:" + dCharset.name()); 365 StringBuilder sber = new StringBuilder("StringBuilder是非线程安全的,"); 366 sber.append("StringBuffer是线程安全的"); 367 sber.append("两种用法差不多,很多方法与string一样"); 368 sber.append("如果不考虑线程安全用StringBuiler "); 369 370 CharSequence chrSeq = sber.subSequence(60, sber.length() - 1); 371 pln(chrSeq.toString()); 372 String strTemp = "53 48 07 03 0B 43 50 C6 00 00 67";// 一条机器执行状态返回指令 373 String testResult = ((strTemp.indexOf("C6") >= 0) ? true : false) ? "执行成功" 374 : "执行失败"; 375 String isOkCode = strTemp.split(" ")[(strTemp.lastIndexOf("C6") / 3) % 21]; 376 pln("这次测试".concat(testResult.intern()) + " 正确代码:" + isOkCode); 377 pln("仪器型号:" 378 + strTemp.substring(strTemp.indexOf("53"), strTemp 379 .indexOf("48"))); 380 pln("指令帧长:" + strTemp.charAt(7)); 381 pln(" 指令效验合:" + strTemp.substring(strTemp.lastIndexOf("00") + 3)); 382 383 } 384 385 // secrurity rmi net beans 合用一个例子 386 // Preferences pf = Preferences.systemRoot(); pln(pf.absolutePath());// 387 public static void systemOperator() { 388 String temp = "自1970年1月1日到现在的毫秒数:"; 389 pln(temp + System.currentTimeMillis()); 390 Properties sysPorp = System.getProperties(); // 获得系统属性 391 Set<Entry<Object, Object>> sysSet = sysPorp.entrySet(); // 1.用Set的entry方式取信息 392 // 2.用map的方式读取 通过下界通配符定义 key值 393 Map<? super String, Object> sysMap = new HashMap<String, Object>(); 394 395 Iterator<Entry<Object, Object>> sysIt = sysSet.iterator();// 同理:sysMap.entrySet().iterator(); 396 for (; sysIt.hasNext();) { 397 Map.Entry<Object, Object> sysEt = (Entry<Object, Object>) sysIt 398 .next(); 399 sysMap.put(sysEt.getKey().toString(), sysEt.getValue()); 400 } 401 // 2.用map的方式读取 通过上界通配符定义 402 Enumeration<? extends Object> sysEm = sysPorp.propertyNames(); 403 while (sysEm.hasMoreElements()) { 404 Object obj = sysEm.nextElement(); 405 // pln(obj + "=" + sysPorp.get(obj));// 通过枚举打印所有的系统参数 406 } 407 // new Properties(System.getProperties()).list(System.out); 3.用输出流的方法 408 // scanner一般都是扫描控制台或者扫描文件 409 Scanner scer = new Scanner(System.in); 410 411 do { 412 System.out.println("请输入命令是否要继续下面的操作(1/0):"); 413 Scanner scer1 = new Scanner("张林,好人嘛,你只能在这输入1才能继续下面的操作"); 414 scer1.useDelimiter(","); 415 while (scer1.hasNext()) 416 pln(scer1.next()); 417 String line = scer.nextLine(); 418 if (line.equals("1")) 419 break; 420 pln(">>>" + line); 421 } while (true); 422 423 try { 424 Thread.currentThread(); 425 Thread.sleep((new Random()).nextInt(1000)); 426 try { 427 String[] cmd = { "cmd", "/C", "copy exe1 exe2" }; 428 Process proc = Runtime.getRuntime().exec(cmd); 429 430 // int exitVal = proc.waitFor(); 431 // System.out.println("Process exitValue: " + exitVal); 432 // Runtime.getRuntime().exit(0); 这个是直接结束jvm,不会执行finally 433 } catch (IOException e1) { 434 // TODO Auto-generated catch block 435 e1.printStackTrace(); 436 } 437 } catch (InterruptedException e1) { 438 // TODO Auto-generated catch block 439 e1.printStackTrace(); 440 } finally { 441 // Calendar.getInstance() 是静态方法,可以直接调用,不用new 442 pln(temp + Calendar.getInstance().getTimeInMillis()); 443 Runtime rt = Runtime.getRuntime(); 444 pln("系统内存大小清理前:" + rt.totalMemory() + " 空闲内存大小清理前:" 445 + rt.freeMemory()); 446 rt.gc(); // 手工垃圾清理 447 pln("系统内存大小清理后:" + rt.totalMemory() + " 空闲内存大小清理后:" 448 + rt.freeMemory()); 449 450 } 451 452 } 453 454 public static void main(String args[]) { 455 // + " 进入函数时间:" + System.currentTimeMillis() + 456 // new JavadocDemo().testMath(); // 匿名调用,不用实例调用 457 // bitOperator();// 用位置到最后,逻辑异或。走到偶数位,科学计数 458 // listOperator(); 459 // systemOperator(); 460 // 匿名类内部类 知识点只是希望大家能够知道有这些知识点,然后有兴趣去深入 461 // 这里需要一个字符串操作的类,spilt的正则表达式方法 462 // java 加密解码 这样省字符 这里加上抽象接口,并用上代理,工厂模式 463 switchOperator(OperatorType.md5Operator); 464 } 465 466 // 通过二进制位置确定操作那几个方法 ,与或关系来解决 467 public static void switchOperator(OperatorType opt) { 468 switch (opt) { // 条件只是整型或者字符型 枚举可以,浮点型不行 469 case all:// 可以带表达式,但不能是变量 470 break; 471 case mathOperator: 472 mathOperator(); 473 break; 474 case bitOperator: 475 bitOperator(); 476 break; 477 case listOperator: 478 listOperator(); 479 break; 480 case systemOperator: 481 systemOperator(); 482 break; 483 case stringOperator: 484 stringOperator(); 485 break; 486 case md5Operator: 487 md5Operator(); 488 break; 489 case bigMathOperator: 490 bigMathOperator(); 491 break; 492 default: 493 System.out.println("没有该类型的操作"); 494 } 495 } 496 497 public static void pln(String str) { 498 System.out.println(str); 499 } 500 501 public static String itbi(int x) { 502 return Integer.toBinaryString(x); 503 } 504 505 protected void finalize() { 506 System.out.println("清理系统垃圾"); 507 } 508 } 509 510 // 动态创建了两个对象 (一个s对象,一个"This is a string"对象) 511 // String s = new String("This is a string"); 512 /* 513 * 使用静态方式创建的字符串,在堆内存的缓冲池中只会产生唯一的一个字符串对象。 514 * 当使用该方式产生同样一个字符串时,堆内存中不再开辟另外一块空间,而是两个引用变量指向同一个字符串对象。 515 */ 516 517 // UTF-32 是4个字节 32位 'A' utf-8 与 uft-16 表示 'a' a的ascii是0X61 utf-8为[0X61] uft-16 518 // [0x00,0X61] 519 // unicode是国际通用编码 这是最统一的编码,可以用来表示所有语言的字符,而且是定长双字节(也有四字节的) 520 // .utf-8编码是unicode编码在网络之间(主要是网页)传输时的一种“变通”和“桥梁”编码。 521 // utf-8在网络之间传输时可以节约数据量。所以,使用操作系统无法搜索出txt文本。 522 // 。其中gbk编码能够用来同时表示繁体字和简体字,而gb2312只能表示简体字,gbk是兼容gb2312编码的。 523 // 运行时类型信息(RunTime Type Information,RTTI)使得你在程序运行时发现和使用类型 524 // 信息。RTTI主要用来运行时获取向上转型之后的对象到底是什么具体的类型。 525 // Class对象的创建发生在类加载(java.lang.ClassLoader)的时候。 526 // java.lang.Class类实现了Serializable、GenericDeclaration、Type、AnnotatedElement四个接口, 527 // 分别实现了可序列化、泛型定义、类型、元数据(注解)的功能。 528 // Class只有一个私有的无参构造方法,也就是说Class的对象创建只有JVM可以完成。 通过代理实现 529 // 如何通过jndi连接数据源 string 格式化输出 正则表达式 java命名规范 谈谈编码规范 530 531 class SystemInfo { 532 /* Windows security masks */ 533 private final static int KEY_QUERY_VALUE = 1; 534 535 /* Constants used to interpret returns of native functions */ 536 private final static int NATIVE_HANDLE = 0; 537 private final static int ERROR_CODE = 1; 538 539 /* Windows error codes. */ 540 private final static int ERROR_SUCCESS = 0; 541 542 private static String absolutePath() { 543 return "/"; 544 } 545 546 private static byte[] windowsAbsolutePath(byte[] WINDOWS_ROOT_PATH) { 547 ByteArrayOutputStream bstream = new ByteArrayOutputStream(); 548 bstream.write(WINDOWS_ROOT_PATH, 0, WINDOWS_ROOT_PATH.length - 1); 549 StringTokenizer tokenizer = new StringTokenizer(absolutePath(), "/"); 550 while (tokenizer.hasMoreTokens()) { 551 bstream.write((byte) '\\'); 552 String nextName = tokenizer.nextToken(); 553 byte[] windowsNextName = toWindowsName(nextName); 554 bstream.write(windowsNextName, 0, windowsNextName.length - 1); 555 } 556 bstream.write(0); 557 return bstream.toByteArray(); 558 } 559 560 public static String getValue(int hkey, byte[] WINDOWS_ROOT_PATH, String key) 561 throws Exception { 562 Class theClass = Class.forName("java.util.prefs.WindowsPreferences"); 563 564 int[] result = openKey1(hkey, windowsAbsolutePath(WINDOWS_ROOT_PATH), 565 KEY_QUERY_VALUE); 566 if (result[ERROR_CODE] != ERROR_SUCCESS) { 567 throw new Exception("Path not found!"); 568 } 569 int nativeHandle = result[NATIVE_HANDLE]; 570 571 Method m = theClass.getDeclaredMethod("WindowsRegQueryValueEx", 572 new Class[] { int.class, byte[].class }); 573 m.setAccessible(true); 574 byte[] windowsName = toWindowsName(key); 575 Object value = m.invoke(null, new Object[] { new Integer(nativeHandle), 576 windowsName }); 577 WindowsRegCloseKey(nativeHandle); 578 if (value == null) { 579 throw new Exception("Path found. Key not found."); 580 } 581 582 byte[] origBuffer = (byte[]) value; 583 byte[] destBuffer = new byte[origBuffer.length - 1]; 584 System.arraycopy(origBuffer, 0, destBuffer, 0, origBuffer.length - 1); 585 586 return new String(destBuffer); 587 } 588 589 public static int WindowsRegCloseKey(int nativeHandle) throws Exception { 590 Class theClass = Class.forName("java.util.prefs.WindowsPreferences"); 591 Method m = theClass.getDeclaredMethod("WindowsRegCloseKey", 592 new Class[] { int.class }); 593 m.setAccessible(true); 594 Object ret = m.invoke(null, new Object[] { new Integer(nativeHandle) }); 595 return ((Integer) ret).intValue(); 596 } 597 598 private static byte[] toWindowsName(String javaName) { 599 StringBuffer windowsName = new StringBuffer(); 600 for (int i = 0; i < javaName.length(); i++) { 601 char ch = javaName.charAt(i); 602 if ((ch < 0x0020) || (ch > 0x007f)) { 603 throw new RuntimeException( 604 "Unable to convert to Windows name"); 605 } 606 if (ch == '\\') { 607 windowsName.append("//"); 608 } else if (ch == '/') { 609 windowsName.append('\\'); 610 } else if ((ch >= 'A') && (ch <= 'Z')) { 611 windowsName.append("/" + ch); 612 } else { 613 windowsName.append(ch); 614 } 615 } 616 return stringToByteArray(windowsName.toString()); 617 } 618 619 public static int[] openKey1(int hkey, byte[] windowsAbsolutePath, 620 int securityMask) throws Exception { 621 Class theClass = Class.forName("java.util.prefs.WindowsPreferences"); 622 Method m = theClass.getDeclaredMethod("WindowsRegOpenKey", new Class[] { 623 int.class, byte[].class, int.class }); 624 m.setAccessible(true); 625 Object ret = m.invoke(null, new Object[] { new Integer(hkey), 626 windowsAbsolutePath, new Integer(securityMask) }); 627 return (int[]) ret; 628 } 629 630 private static byte[] stringToByteArray(String str) { 631 byte[] result = new byte[str.length() + 1]; 632 for (int i = 0; i < str.length(); i++) { 633 result[i] = (byte) str.charAt(i); 634 } 635 result[str.length()] = 0; 636 return result; 637 } 638 639 }
浙公网安备 33010602011771号