自动装箱和拆箱 枚举 反射 数组反射的应用。ArrayList和HashSet

来源:互联网 发布:兴趣部落签到软件 编辑:程序博客网 时间:2024/06/05 03:51

 

[java] view plaincopyprint?
  1. /* 
  2. eclipse的使用技巧。可变参数。基本数据类型自动装箱和拆箱。枚举。反射。数组反射的应用。ArrayList集合和HashSet集合。 
  3. JavaBean。 
  4. */  
  5.   
  6.   
  7. /*基础加强和JDK1.5新特性. 
  8.  
  9.     基础很重要,就业就看基础掌握的好不好. 
  10.     但不能天天学基础,只有通过高级的应用,才能知道基础怎么用. 
  11.     就像一年纪的题目,五年纪的人来做能拿满分. 
  12.  
  13. eclipse的使用技巧。 
  14.     MyEclipse是eclipse的插件。可以处理j2ee. 
  15.     eclipse用javaw.exe运行,不再是java.exe. 
  16.  
  17.     ide-->itegrity development environment (集成开发环境) 
  18.  
  19.     1)Workspace与project 
  20.         必须要求:会切换工作间与导入项目。 
  21.  
  22.     IDE开发工具都支持使用工程化方式管理一个项目的程序开发过程。一般 
  23.     来说一个相对独立的项目就是一个工程,一个项目中涉及的多个java文件,资源 
  24.     文件等用一个工程进行管理。 
  25.  
  26.     点window-->点击Preferences-->Java-->Compiler(编译器)。有java版本。编译时版本。 
  27.     Java->Installed JREs(java运行版本) 。运行时版本。 
  28.  
  29.     切换工作间:File->Switch Workspace.选择Others,OK后就新建。 
  30.  
  31.     新建一个工程,普通的java工程,New->Project->java Project->输入工程名字。这时可以选用jre版本。 
  32.     在src上,可以选择新建class.会选择新建包名。良好的习惯应该有包名。 
  33.  
  34.     修改工程名字,-->Refactor(重构),新建立的工程配置环境可能改变,如快捷键。 
  35.  
  36.     配置快捷键。window-->Preferences->General-->Keys.输入content. 
  37.     选择content Assist-->按下UnbindCommand(解除绑定)。在下面可以Binding,按下Alt键同时按其他。如/键。 
  38.      
  39.     2)View与调试debug 
  40.     打个断点,程序上选择bebug  as run ,出来调试窗口-->选中变量,点右键->Watch. 
  41.     想回去写程序,在右上角选择java视图。 
  42.     Window->show view->other可以调试视图。 
  43.  
  44.     3)配置编译和运行java版本。 
  45.     点window-->点击Preferences-->Java-->Compiler(编译器)。有java版本。编译时版本。 
  46.     Java->Installed JREs(java运行版本) 。运行时版本。 
  47.     用高版本的jdk编译出来的程序,用低版本不能运行。 
  48.     高版本的jre可以运行低版本jdk编译出来的java程序。 
  49. */  
  50. /* 
  51. 可变参数 
  52.     特点:放在未尾。 
  53.     三点...位于变量类型和变量名之间时,前后有无空格都可。 
  54.     调用可变参数的方法时,编译器为该可变参数隐含创建一个 
  55.     数组,在方法体中以数组的形式访问可变参数。 
  56.     public static int getSun(int x,int ... args){ 
  57.         int sum = x; 
  58.         for(int i=0;i<args.length;i++){ 
  59.             sum += args[i]; 
  60.         } 
  61.         return sum; 
  62.     } 
  63.     面试题。overload与override 的区别. 
  64.  
  65.  
  66.  
  67. 基本数据类型的自动装箱和拆箱 
  68.     自动装箱 
  69.     Integer num = 12; 
  70.     自动拆箱 
  71.     System.out.println(num+10); 
  72.  
  73.     基本数据类型的对象缓存。 
  74.     Integer num1 = 12; 
  75.     Integer num2 = 12; 
  76.     System.out.println(num1==num2);//true 
  77.     //基本类型整数在(-128~127)之间,就不创建新对象,大于区间就创建。 
  78.     //享元模式。 
  79.     Integer num1 = 129; 
  80.     Integer num2 = 129; 
  81.     System.out.println(num1==num2);//false 
  82.  
  83.     Integer num1 = Integer.valueOf(12); 
  84.     Integer num2 = Integer.valueOf(12); 
  85.     System.out.println(num1==num2);//true,大于127同样false. 
  86. */  
  87. /* 
  88. 枚举: 
  89.     枚举的作用介绍。jdk1.5新特性。 
  90.     枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个。否则, 
  91.     编译器会报错。这个值在编译时期就被控制。 
  92. */  
  93.   
  94. public abstract class WeekDay1 {  
  95.   
  96.     /**普通类模拟枚举 
  97.      * @param args 
  98.      */  
  99.     private WeekDay1(){};//让别人创建不了对象  
  100.     public static final WeekDay1 SUN = new WeekDay1() {  
  101.         @Override  
  102.         public WeekDay1 nextDay() {  
  103.             // TODO Auto-generated method stub  
  104.             return MON;  
  105.         }     
  106.     };  
  107.     public static final WeekDay1 MON = new WeekDay1() {  
  108.         @Override  
  109.         public WeekDay1 nextDay() {  
  110.             // TODO Auto-generated method stub  
  111.             return SUN;  
  112.         }  
  113.     };  
  114.       
  115.     /*public WeekDay nextDay(){//独立方法去写 
  116.         if(this == SUN){ 
  117.             return MON; 
  118.         }else{ 
  119.             return SUN; 
  120.         } 
  121.     }*/  
  122.     public abstract WeekDay1 nextDay();//让别人实现它。  
  123.       
  124.     public String toString(){  
  125.         return this == SUN?"SUN":"MON";  
  126.     }  
  127. }  
  128.   
  129.   
  130. public class EnumTest {  
  131.   
  132.     /** 
  133.      * @param args 
  134.      */  
  135.     public static void main(String[] args) {  
  136.         // TODO Auto-generated method stub  
  137.         WeekDay1 weekDay = WeekDay1.MON;  
  138.         System.out.println(weekDay.nextDay());  
  139.           
  140.         WeekDay weekDay2 = WeekDay.FRI;  
  141.         System.out.println(weekDay2);  
  142.         System.out.println(weekDay2.name());  
  143.         System.out.println(weekDay2.ordinal());  
  144.         System.out.println(WeekDay.valueOf("SUN").toString());  
  145.         System.out.println(WeekDay.values().length);  
  146.     }  
  147.       
  148.     public enum WeekDay {  
  149.         SUN(1),MON,TUE,WED,THI,FRI,SAT;//分号,所有其他信息都必须列于元素列表之后。  
  150.         private WeekDay() {//枚举的构造方法必须私有。  
  151.             System.out.println("frist");  
  152.         }  
  153.         private WeekDay(int day) {  
  154.             System.out.println("second");  
  155.         }  
  156.     }     
  157. }  
  158. /*枚举就是一个类,枚举的成员就是静态成员。 
  159.     //所有其他信息都必须列于元素列表之后。 
  160.     //枚举的构造方法必须私有。 
  161.     //枚举的成员相当于一个类的实例对象。对象之间用,号隔开 
  162.     SUN(1)相当于创建元素用哪个构造方法。 
  163.     SUN,SUN():调用空的。 
  164.  
  165.     实现带抽象方法的枚举. 
  166.  
  167.     如果枚举只有一个成员,那可以了解为单例设计模式。 
  168.  
  169. */  
  170.   
  171.     public enum TrafficLamp {  
  172.         RED(30){  
  173.   
  174.             @Override  
  175.             public TrafficLamp nextLamp() {  
  176.                 // TODO Auto-generated method stub  
  177.                 return GREEN;  
  178.             }  
  179.         },  
  180.         GREEN(45){  
  181.   
  182.             @Override  
  183.             public TrafficLamp nextLamp() {  
  184.                 // TODO Auto-generated method stub  
  185.                 return YELLOW;  
  186.             }},  
  187.         YELLOW(5){  
  188.   
  189.             @Override  
  190.             public TrafficLamp nextLamp() {  
  191.                 // TODO Auto-generated method stub  
  192.                 return RED;  
  193.             }  
  194.         },  
  195.         public abstract TrafficLamp nextLamp();//抽象方法,那么每个成员都要实现。  
  196.         private int time;  
  197.         private TrafficLamp(int time){this.time = time;}  
  198.     }  
  199.   
  200. /*反射的基石->Class类 jdk1.2 
  201. Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class. 
  202.     对比。众多的人用一个什么类表示?众多的Java类用一个什么类表示。 
  203.     人——>Person       Person p1 = new Person();Person p2 = new Person(); 
  204.     java类-->Class    Class cls1 = ?;没有构造方法,或方法是私有的,不能直接new. 
  205. 如何得到各个字节码对应的实例对象(Class类型) 
  206.     内存中的每份字节码,就是对应的实例对象。通过对象拿字节码。p1.getClass(); 
  207.     还有一个方法得到类的字节码,Class类的静态方法:Class.forName("java.lang.String"); 
  208. 如何得到各个字节码对应的实例对象(Class类型) 
  209. 三种:类名.class,如:System.class 
  210.     对象.getClass()如:new Date().getClass(); 
  211.     Class.forName("类名"),如:Class.forName("java.util.Date"); 
  212. 反射主要用第三种,因为在写程序时还不知道类的名字. 
  213.  
  214. 九个预定义Class实例对象。 
  215. 八个基本类型:boolean,byte,char,short,int,long,float,double. 
  216. 还有一个void. 
  217.     int.class.isPrimitive();//是否是原始类型。 
  218.     int.class = Integer.TYPE; 
  219.     Integer.TYPE;代表基本类型。 
  220.     注意:int.class == Integer.class;//不是一个。 
  221.  
  222.     数组类型的实例变量 
  223.     int[].class.isPerimitive();//不是 
  224.     Class.isArray();//判断是否是数组。字节码。isArray(); 
  225.  
  226.     总之:只要在源程序中出现的类型,都有各自的Class实例对象。例如:int[]... 
  227.     public static void main(String[] args) { 
  228.         // TODO Auto-generated method stub 
  229.         System.out.println(int.class == Integer.class);//不相等 
  230.         System.out.println(int.class == Integer.TYPE);//相等 
  231.         System.out.println(int[].class.isPrimitive());//不是原始 
  232.         System.out.println(int[].class.isArray());//是数组 
  233.     } 
  234. */  
  235. /* 
  236. 反射:总之:反射就是把Java类中的各种成分映射成相应的java类。 
  237.  
  238. Constructor 类(构造函数的反射) 
  239.      
  240.     得到某个类中的所有的构造方法。 
  241.     例子;ConStructor [] cons = Class.forName("java.lang.String").getConstructors(); 
  242.     得到某一个构造方法: 
  243.     ConStructor constructor1 = Class.forName("java.lang.String").getConstructor(StringBuffered.class); 
  244.     拿到构造方法后,就可以去构造一个实例对象。 
  245.     String str2 = (String)constructor1.newInstance(new StringBuffer("abc")); 
  246.     //程序编译时不知道是哪个构造方法的,只有运行时才知道。(String). 
  247.     //获得方法时要用到类型.class,使用方法时要用到相应类型的对象。 
  248.         clazz.newInstance(),运行空构造方法,得到一对象。 
  249.  
  250.         Class clazz = Class.forName("java.lang.String");//拿字节码 
  251.         Constructor con = clazz.getConstructor(StringBuffer.class);//拿某一个构造函数 
  252.         String str = (String)con.newInstance(new StringBuffer("abc"));//要传对应的sb,不能是("abc") 
  253.         System.out.println(str); 
  254. */  
  255.   
  256. import java.lang.reflect.Constructor;  
  257. public class RefPointDemo {  
  258.     public static void main(String[] args) throws Exception {  
  259.         // TODO Auto-generated method stub  
  260.         /*暴力反射私有的构造函数*/  
  261.         Class clazz = new RefPoint().getClass();  
  262.         Constructor con = clazz.getDeclaredConstructor(int.class,int.class);//Declared是所有的,包括私有。  
  263.         con.setAccessible(true);//设为可使用。  
  264.         RefPoint refpoint = (RefPoint)con.newInstance(5,6);  
  265.         System.out.println(refpoint);  
  266.     }  
  267. }  
  268.  class RefPoint {  
  269.   
  270.     public static int x ;  
  271.     private static int y;  
  272.     public RefPoint(){}  
  273.     private RefPoint(int x, int y) {  
  274.         super();  
  275.         this.x = x;  
  276.         this.y = y;  
  277.     }  
  278.     public String toString()  
  279.     {  
  280.         return "x:"+x+",y:"+y;  
  281.     }  
  282. }  
  283. /* 
  284. Field类:(成员变量的反射) 
  285.     main()...{ 
  286.         RefPoint ref1 = new RefPoint(3,5); 
  287.         Class clazz = ref1.getClass(); 
  288.         Field fi = clazz.getDeclaredField("y");//私有的成员y就要用这个方法。 
  289.         fi.setAccessible(true);//私有的成员y必须为可见 
  290.         int yy =(Integer)fi.get(ref1);//这里才具体到哪个对象一个值 
  291.         System.out.println(yy); 
  292.     } 
  293. */  
  294.   
  295. import java.lang.reflect.Field;  
  296. //将任意一个对象中的所有String类型的成员变量所对应字符串内容中的"b"改成"a"。  
  297. public class RefFileTest {  
  298.     public static void main(String[] args) throws Exception {  
  299.         StringSSS sss = new StringSSS();  
  300.         show(sss);  
  301.         System.out.println(sss);  
  302.     }  
  303.     public static void show(Object obj) throws Exception{  
  304.         Class clazz = obj.getClass();  
  305.         Field[] field = clazz.getDeclaredFields();  
  306.         for(Field fi:field){  
  307.             if(fi.getType()==String.class){//获取成员的类型,同一个类型判断用==.  
  308.                 String oldstr = (String)fi.get(obj);//如果是String,就传入对象,拿到具体的值  
  309.                 String newstr = oldstr.replace('b''a');//替换b->a.  
  310.                 fi.set(obj,newstr);//再设置到原对象上。  
  311.             }  
  312.         }  
  313.     }  
  314. }  
  315. class StringSSS{  
  316.     public String str1 = "ball";  
  317.     public static  String str2 = "baskball";//静态可以被修改,final修饰后常量不可以。  
  318.     public String str3 = "itcast";  
  319.     public String toString(){  
  320.         return "Str1:"+str1+",Str2:"+str2+",Str3:"+str3;  
  321.     }  
  322. }  
  323. /*以前老师不是讲String一初始化,值就不可以改变吗? 
  324. 使用反射,没有改变引用地址,也可以改变它的值???*/  
  325.   
  326. /* 
  327. Method类。 
  328.     代表某一类中的成员方法。 
  329.     invoke(str1,1),如果str1为null,那么为静态方法,不需要对象来调用的。 
  330.     Method methodChatAt = String.class.getMethod("chatAt",int.class); 
  331.     因为一个类中的方法有很多,得到具体的方法用到(方法名,XX),而这个方法有可能被重载, 
  332.     所以要用到参数列表的字节码,综合就是(方法名,参数.class);就是得到具体哪个方法。 
  333.     再调用这个方法。methodChatAt.invoke(str1,1);str1表示作用的某个对象。 
  334. */  
  335.     public static void main(String[] args) throws Exception {  
  336.         // TODO Auto-generated method stub  
  337.         String str = "abc";  
  338.         Method method = String.class.getMethod("charAt",int.class);//拿到某个方法  
  339.         Character ch = (Character)method.invoke(str, 1);//这里可以是(Character),不可以是char???返回的Object不能转变char?  
  340.         System.out.println(method.invoke(str, 1));//str表示作用的某个对象,为null时表示为静态方法。不需要对象调用。  
  341.         System.out.println(ch+".....");//1.4版本前,invoke(str, 1))写为invoke(str, new Object[]{1}).传入Object数组  
  342.     }  
  343.       
  344. /*练习,自己写程序,调用人家的main()方法,用反射方式。 
  345.     为什么要用反射的方式去调? 
  346.     写程序时不知道要执行哪个类的,传入参数才知道要调用哪个。  
  347.  
  348.     1.5因为兼容1.4,所以传入(null,new String("111","333","222"))这时会打开数组,参数就不对了 
  349.     应该改成(null,new Object[]{(new String[]{"111","333","222"})}),先打好包,解开后还是我想要传的. 
  350.     还可以这样做,直接告诉编译器,我就是传给了你一个对象。(null,(Object)new String[]{"111","333","222"}) 
  351.     告诉它不要拆了。 
  352. */  
  353.   
  354. public class MethodDemo {  
  355.   
  356.     public static void main(String[] args) throws Exception {     
  357.         //new MethodSSS().main(new String[]{"111","222","333"});//没用反射,我们一般都是这样调用,  
  358.           
  359.         //使用反射怎么调用呢?通过参数传入我想要运行哪个类的主函数。  
  360.         Method startMethod = Class.forName(args[0]).getMethod("main", String[].class);  
  361.         startMethod.invoke(null,(Object)new String[]{"111","222","333"});//数组参数这里要打包。  
  362.       
  363.     }  
  364. }  
  365. class MethodSSS{  
  366.     public static void main(String[] args){  
  367.         for(int x=0;x<args.length;x++){  
  368.             System.out.println(args[x]);  
  369.         }  
  370.     }  
  371. }  
  372.   
  373. /* 
  374. 数组的反射, 
  375.     具有相同的元素类型的同维数组的字节码是同一个。可以相等==. 
  376.  
  377.     基本数据类型不是Object.所以在Arrays.asList()时,基本数据类型转换时,是将整个 
  378.     数组转换成的,因为一个基本数据类型,不能转换成Object.如int 
  379.  
  380.     调用Arrays.asList()时,高版本满足低版本,所以jdk1.4时,asList(Object[] obj),参数,不符合 
  381.     就返回用1.5方法,变成可变参数asList(T...a); 
  382.  
  383. */  main(){  
  384.         int[] a1 = new int[3];  
  385.         int[] a2 = new int[4];  
  386.         String[] a3 = new String[]{"1","2","3"};  
  387.         int[][] a4 = new int[3][4];  
  388.           
  389.         System.out.println(a1.getClass()==a2.getClass());//true  
  390.         //System.out.println(a1.getClass()==a3.getClass());//错误  
  391.         //System.out.println(a1.getClass()==a4.getClass());//错误  
  392.         System.out.println(a1.getClass().getName());//[I  
  393.         System.out.println(a1.getClass().getSuperclass().getName());//java.lang.Object  
  394.         System.out.println(a3.getClass().getSuperclass().getName());//java.lang.Object  
  395.           
  396.         Object ab1 = a1;  
  397.         Object ab2 = a3;  
  398.         Object ab3 = a4;  
  399.         Object[] ab4 = a1;//只有这个提示报错,说明int不能转成Object  
  400.         Object[] ab6 = a3;  
  401.         Object[] ab5 = a4;  
  402.         System.out.println(Arrays.asList(a1));//[[I@15ff48b]  
  403.         System.out.println(Arrays.asList(a3));//{1,2,3}  
  404.     }  
  405.   
  406. //数组反射的应用。  
  407.     main(){  
  408.         //printObj(a3+"...");  
  409.         printObj(a3);//这样可以打印  
  410.         printObj("xyz");  
  411.           
  412.     }  
  413.     public static void printObj(Object obj){  
  414.         Class clazz = obj.getClass();  
  415.         if(clazz.isArray()){//拿到字节码判断是不是数组  
  416.             int len = Array.getLength(obj);//拿到数组长度  
  417.             for(int x=0;x<len;x++){  
  418.                 System.out.println(Array.get(obj, x));//[Ljava.lang.String;@affc70...为什么我的打不出来???  
  419.                                                         //因为我在上面加了...,printObj(a3+"...");  
  420.             }  
  421.         }else{  
  422.             System.out.println(obj);  
  423.         }  
  424.     }  
  425.   
  426. /* 
  427.     ArrayList集合和HashSet集合,HashCode()分析。 
  428.     ArrayList集合,是有顺序的,判断相同与否的依据是:对象的equals()方法,默认比较的是地址值,要想相等,就要重写equals()方法。 
  429.     HashSet集合:是无序的,判断的依据是Hashcode(),相同再比较equals(). 
  430.  
  431.     HashCode()值,让具备HashCode存储的对象,在内在中对应相应的Hash区域。 
  432.     当HashCode依据的算法存储进内存后,就不要修改算法依据的相应的值了。 
  433.     因为一改了之后,HashCode()的值也会改变。会内存泄露。 
  434.     内存泄露:对象使用后,没有被释放。 
  435.     父类引用Collection 分别建立ArrayList,HashSet子类对象,比较它的区别。如元素的大小。 
  436.     复写各方法,可发现不同。 
  437. */  
  438.   
  439. /* 
  440.     反射的作用->实现框架功能。 
  441.     前面已经小小使用一回了,就是输入名字,运行它的主函数。 
  442.  
  443.     框架要解决的核心问题。 
  444.     因为在写程序时无法知道要被调用的类名,所以在程序中无法直接用new某个类的实例对象了。 
  445.     要用反射方式来做。 
  446. */  
  447. public class RefTest {  
  448.   
  449.     /**利用反射实现一个小框架, 
  450.      * 在一个文件中写入内容。config.txt,className = java.util.ArrayList  
  451.      * @getRealPath();javaweb开发时,可以得到文件的路径。实际开发一定要完整的路径。InputStream("config.txt"); 
  452.      */  
  453.     public static void main(String[] args) throws Exception {  
  454.         // TODO Auto-generated method stub  
  455.         InputStream ips = new FileInputStream("config.txt");//读取文件,实际开发要用到绝对路径  
  456.         Properties prop = new Properties();  
  457.         prop.load(ips);//文件载入内存  
  458.         ips.close();  
  459.         String className = prop.getProperty("className");//得到文件名字  
  460.         Class clazz = Class.forName(className);  
  461.         //Constructor con = clazz.getConstructor();//得到构造函数  
  462.         //Collection coll = (Collection)con.newInstance();//创建对象  
  463.         Collection coll = (Collection)clazz.newInstance();//空的构造方法直接这样。  
  464.     }  
  465. }  
  466. /* 
  467. 用类加载器的方式管理资源和配置文件。 
  468. 原理:程序要运行,要加载.class文件,用什么加载这个文件呢?那就是类加载器, 
  469. 它能够加载.class文件,为什么就不能加载普通文件呢?肯定能。 
  470. 实例对象.getClass().getClassLoader().getResourceAsStream(cn/itcast/day1/config.txt);注意cn前不加/ 
  471. 文件在src目录下的。java文件,一保存eclipse就会自动编译到bin目录下去,非.java会拷贝过去。 
  472. .getResourceAsStream()这个方法只读,又读又写,还是用上面那种。InputStream ips = new FileInputStream("config.txt")。 
  473.  
  474. .getClass().getClassLoader().getResourceAsStream()这种方法加载麻烦,那么.class有没有直接加载的方法呢? 
  475. .getClass().getResourceAsStream("resources/文件名")相对路径,当最前面有/时,要用绝对路径,这是用字节码的简单直接方法 
  476. 加载文件,实际上还是用的类加载器加载实现的。 
  477. */  
  478. /* 
  479. 由内省引出的JavaBean的讲解。 
  480.     内省->IntroSpector.-->主要用于对JavaBean进行操作 
  481.     什么是JavaBean,特殊的java类,方法按特殊的规定起名。 
  482.     例如有个age属性,有方法 int getAge(); void setAge(int age). 
  483.     JavaBean也是一个java类,可以进行java类的所有普通操作。 
  484.     1.int getAge();没有参数,返回值是int 
  485.     2.void setAge(int age)。有参数,返回值是void 
  486.     有这二个条件就可以当作JavaBean操作了 
  487. */  
  488. class Person  
  489. {  
  490.     private int x;  
  491.     public int getAge()//public  
  492.     {  
  493.         return x;  
  494.     }  
  495.     public void setAge(int age)  
  496.     {  
  497.         this.x = age;  
  498.     }  
  499. }  
  500. /* 
  501. 上面的Person类当作普通的java类来看,有一个x的成员属性。 
  502. Person类当作一个JavaBean 来看,有一个Age属性。 
  503. Age-->age如果第二个字母是小的,把第一个字母变成小的。 
  504. gettime-->time; 
  505. settime-->time 
  506. getCPU-->CPU,为了整洁。不是cPU 
  507.  
  508. 当JavaBean处理,可以更方便,简单。 
  509.     在Java EE开发中,很多环境就要求按照JavaBean方式进行操作。 
  510.     JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。 
  511. */  
  512.   
  513. import java.beans.IntrospectionException;  
  514. import java.beans.PropertyDescriptor;  
  515. import java.lang.reflect.InvocationTargetException;  
  516. import java.lang.reflect.Method;  
  517. //对javabean的简单操作,获取属性。  
  518. public class JavaBeanDemo {  
  519.   
  520.     public static void main(String[] args) throws Exception {  
  521.         Point p1 = new Point(3,5);  
  522.           
  523.         String propertyName = "x";  
  524.         //普通方式:"x"->"X"->"getX"->MethodGetX-->x获取过程麻烦  
  525.           
  526.         //1.得到名称为propertyName的内省。  
  527.         Object retVal = getProperty(p1, propertyName);//这里用了方法抽取  
  528.         System.out.println(retVal);  
  529.           
  530.         Object obj = 7;  
  531.           
  532.         setProperty(p1, propertyName, obj);  
  533.            
  534.          //Object retVal2 = methodGetX.invoke(p1);  
  535.            
  536.          System.out.println(p1.getX());//当作普通类来获取  
  537.         //System.out.println(retVal2);  
  538.     }  
  539.   
  540.     private static void setProperty(Object p1, String propertyName, Object obj)  
  541.             throws Exception{  
  542.         PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,//这是名称  
  543.                 p1.getClass());//  
  544.         Method methodSetX = pd2.getWriteMethod();  
  545.          methodSetX.invoke(p1, obj);  
  546.     }  
  547.   
  548.     private static Object getProperty(Object p1, String propertyName)  
  549.             throws Exception {  
  550.         PropertyDescriptor pd = new PropertyDescriptor(propertyName,//这是名称  
  551.                 p1.getClass());//得到javaBean属性,得到哪个对象的内省。  
  552.           
  553.         //2.下面就可以得到它的读的方法。  
  554.         Method methodGetX = pd.getReadMethod();//这里就是得到x的方法。  
  555.           
  556.         //3.应用在哪个对象上,没有参数后面就不写.第2,3步就是反射。  
  557.         Object retVal = methodGetX.invoke(p1);  
  558.         return retVal;//简单方法  
  559.     }  
  560. }  
  561. class Point{  
  562.     Point(int x,int y){  
  563.         this.x = x;  
  564.         this.y = y;  
  565.     }  
  566.     public int getX() {  
  567.         return x;  
  568.     }  
  569.     public void setX(int x) {  
  570.         this.x = x;  
  571.     }  
  572.     public int getY() {  
  573.         return y;  
  574.     }  
  575.     public void setY(int y) {  
  576.         this.y = y;  
  577.     }  
  578.     private int x;  
  579.     private int y;  
  580. }  
  581.   
  582. /*下面这个内省的复杂方法。为什么要看?程序设计中经常用这种思想。 
  583. 在程序中把一个类当作JavaBean来看,就是调用IntroSpector.getBeanInfo方法, 
  584. 得到的是Beaninfo对象封装了把这个类当作javaBean看的结果信息。 
  585. */  private static Object getProperty(XY xy, String name)  
  586.             throws IntrospectionException, IllegalAccessException,  
  587.             InvocationTargetException {  
  588.         /* 
  589.          * PropertyDescriptor pd = new PropertyDescriptor(name,xy.getClass()); 
  590.          
  591.         Method methodGetX = pd.getReadMethod(); 
  592.         Object retVal = methodGetX.invoke(xy); 
  593.         return retVal//;简单方法 
  594.         */  
  595.         BeanInfo bfs = Introspector.getBeanInfo(xy.getClass());//记住这个Introspector类名  
  596.         PropertyDescriptor[] pds = bfs.getPropertyDescriptors();//所有属性信息  
  597.         Object retVal = null;  
  598.         for(PropertyDescriptor pd:pds){  
  599.             if(pd.getName().equals(name)){//名字相同,找到了。  
  600.                 Method methodGetX = pd.getReadMethod();  
  601.                 retVal = methodGetX.invoke(xy);  
  602.             }  
  603.         }  
  604.         return retVal;//复杂方法  
  605.     }  
  606.   
  607.     /* 
  608.     使用工具操作javaBean 
  609. 先去网上下载工具包JavaBean包,解压。 
  610.  
  611. 然后把工具包的.jar文件,加到我们的java工程中来。 
  612. 局限方法:右击工程名,Build Path-->Configure Build Path-->Libraries->Add  External JARS. 
  613. 这种方法不会随着工程转换。换了电脑就运行不了。 
  614.  
  615. 下面这种方法是放到工程里面转移。 
  616. 在工程下建立一个目录,lib文件夹,然后把刚才的.jar拷贝进来lib。 
  617. 然后选择.jar文件,Build Path-->Add to Build Path.前面的图标会变成小奶瓶。 
  618.  
  619. Utils怎么应用呢? 
  620. 里面有静态方法。 
  621. BeanUtils.getProperty(pt1,"x");会有错。没有日志包。 
  622. 把日志包的.jar也增加到Build Path.再运行。就可以了。 
  623. set,get这里都是用字符串操作的,因为web上的数据都是用字符串传送的。 
  624.  
  625. 对比另外一个类的静态方法,就是用int操作。如下。 
  626. PropertyUtils.setProperty(pt1,"x",9),这个是用属性本身的类型进行操作。 
  627.  
  628. javaBean 可以和Map相互转换。Utils工具有这样的方法。 
  629.  
  630. java7里面,map对象可以这样定义。 
  631. Map map = (name:"zxx",age:18); 
  632.  
  633.  
  634. */  

android培训、java培训、期待与您交流!
原创粉丝点击