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 }

 

posted @ 2013-05-22 19:48  RecordMe  阅读(1095)  评论(0)    收藏  举报