黑马程序员_高新技术_知识总结一

------- Windows Phone 7手机开发.Net培训、期待与您交流! -------

 

对枚举、可变参数、反射机制、内省的理解

1.   自动装箱和拆箱的理解;

A.   Integer it= 213;

B.        Integer i3 = Integer.valueOf(213);

以上2种写法都是正确的,a会自动装箱成Integer对象;这个是1.5的新特性;

 

2.         枚举

A.   枚举是一个类,这里可以说是内部类;枚举里面的每一个元素都是一个对象;

B.   调用枚举类的时候,就会初始化枚举类里面的所有对象,就会调用所有对象对应的构造方法;

C.   在这里我们也可以指定我们的对象调用哪个构造方法,指定的语法是,在对象后面加个()()传相应的参数;就会调用相应的带参数的构造方法;

D.   枚举类的构造方法必须是私有的;并且枚举里面的构造方法位置,必须放在枚举对象的后面;

E.   字符串变成对象方法WeekDay w =WeekDay.valueOf("SUN")

F.   枚举类获取数组的长度方法;WeekDay.values().length

G.   内部类的应用;

       public enum TrafficLamp{

//RED就是父类的引用创建子类的对象,这里有抽象方法,还有复写了抽象方法的具体内容,所以是内部类规则的写法;

//此外这个枚举对象还传递了时间参数,调用了枚举类里面的带参数的构造方法;

       RED(30){

           public  TrafficLamp nextLamp(){

              return GREEN;

           }

       },

       public abstract TrafficLamp nextLamp();

       private int time;

       private TrafficLamp(int time){this.time = time;}

}

3.   JDK1.5的特性,可变参数;

A.   可变参数必须放在参数列表的最后面;

B.   可变参数是一个数组,可以用数组的形式打印出来;

C.   可变参数的定义;public static int add(int x,int... args){}

4.   静态导入,JDK1.5的特性;

这个就是不用通过类名去调用方法了,可以直接用;

如;求最大值,平常是用Math. max(3, 6)

通过使用import static java.lang.Math.*; 就可以这么用了max(3, 6)

5.   反射的一些用法;

A.   反射的概念;反射就是把java类中的各种成分映射成相应的java类;

反射的基石——Class类,和calss关键字是有区别的,Class类是类的一个总称,代表java类, Class类里面有很多方法,它和其他的类性质一样;就是一个java

 

B.   得到字节码的有三种方式;

要是同一个类的话,这三种方式获取的是同一个字节码;

1)类名.对象;             system.class。得到字节码对象;

2)对象.getClass()        new Date().getClass();

3Class.forName("类名") 例如;Class.forName("java.util.Date")

 反射一般用第3种方式;

C.    

1)   type包装着基本数据类型的字节码;所以是一样的字节码;

int.class == Integer.TYPE 他们是一样的字节码;

2)   int是基本类型的字节码;int.class == Integer.class

Integer是引用类型的字节码,所以不一样;

3)   这个是数组类型的字节码,不是基本类型字节码,

int[].class.isPrimitive()

4)   比较数组的字节码;数组的维数相同,并且是同一种类型,字节码是相等的;

 

D.   获取构造方法;

//比如获取这个类的构造方法new String(new StringBuffer("abc"))

我们得到String类的字节码,然后获取String类相应的带有参数的构造函数;StringBuffer.class是表示选择带有StringBuffer类型参数的哪个构造方法;

Constructor  constructor1 = String.class.getConstructor

(StringBuffer.class);

E.   通过构造方法,我们创建我们想要的对象,这时需要传递一个对象进去;因为我们需要接收对象,所以要传递;

String str2 =(String)constructor1.newInstance

(new StringBuffer("abc"));

F.    

1)   获取对象身上的值要用fieldY.get(pt1),就是说先获取字段,再用字段获取对象上的该字段;

ReflectPoint pt1 = new ReflectPoint(3,5);

Field fieldY = pt1.getClass().getField("y");

System.out.println(fieldY.get(pt1))获取x字段值

2)   获取声明过的私有字段方法;

Field fieldX = pt1.getClass().getDeclaredField("x");

设置私有字段上的变量可以访问;这样才能取得私有的字段变量值;

fieldX.setAccessible(true);

System.out.println(fieldX.get(pt1));获取y字段值;

G.   我们获取反射的方法;

参数charAt是想要获取的方法的名字,第二个参数是想要获取的方法的参数的类型int;所以用int.class;

Method methodCharAt = String.class.getMethod("charAt", int.class);

//再用这个方法去调用我们得到的反射方法;str1是字符串变量,值为abc的话;

那么我们打印出来的值就是abc的第一个位置bb就是结果;

methodCharAt.invoke(str1, 1)

 

H.   利用反射的方式来求出元素;能求出数组中的元素,也能求出单个元素;传递什么,就能求出什么;

//打印你给我传递过来的参数;

    private static void printObject(Object obj) {

//     得到字节码;

       Class clazz = obj.getClass();

//     判断是不是数组;是数组我们就这样操作;

       if(clazz.isArray()){

           int len = Array.getLength(obj);

           for(int i=0;i<len;i++){

//         通过数组加索引的方式来获取元素;

              System.out.println(Array.get(obj, i));

           }

//         不是数组我们就打印出来你给给我的单个元素;

       }else{

           System.out.println(obj);

       }

    }

I.   通过反射的方式,来修改类中字符串的方法;反射机制;我们这里传递的参数是一个类的对象,功能是改变这个类里面变量的值;

private static void changeStringValue(Object obj) throws Exception {

//     获取这个传入类的所有字段;

//     Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。

//     反射的字段可能是一个类(静态)字段或实例字段。

       Field[] fields = obj.getClass().getFields();

       for(Field field : fields){

//  字节码是相等的,所以用== 号;如果这个字段的类型是String类的字节码

           if(field.getType() == String.class){

//我们就会通过对象,用字段获取我们的字符串类型的成员变量;field代表的是成员变量;

              String oldValue = (String)field.get(obj);

//得到新的串

              String newValue = oldValue.replace('b', 'a');

//将指定对象变量上此 Field 对象表示的字段设置为指定的新值。   

              field.set(obj, newValue);

           }

       }

    }

6.   反射;通过配置文件的用法;

A.   getClassLoader()这个是获得类加载器,getResourceAsStream获得资源;

//ips通过决定路径,来获得我们的配置文件,用输入流接收

InputStream ips = ReflectTest2.class.getResourceAsStream

("/cn/itcast/day1/resources/config.properties");

       Properties props = new Properties();

//存储我们想要的键值对;

       props.load(ips);

//必须关闭流,因为不关闭可能由于,对象关联的系统资源没有被释放,会产生内存泄露;

       ips.close();

//获取我们的类名字;

String className = props.getProperty("className");

//通过反射的方式。来获取collections对象;通过不带参数的构造方法方式来获取集合对象;我们的配置文件里面装的是ArrayList它有无参数的构造方法所以可以这么用;

Collection collections (Collection)Class.forName(className).newInstance();

这里我们就可以操作集合。可以添加元素等功能了,要是我们不喜欢ArrayList集合装的元素;在配置文件中也可以换成别的;这样的程序有扩展型;想换集合不用动源码了;直接动配置文件;

7.         hashcode的存储模式;

1Hashcode本身里面有很多区域,我们通过计算hashcode的值,来确定里面的区域,这样可以提高效率。

但是注意一点就是,hashcode元素存储集合完毕后,不能对其进行删除操作,因为我们添加的元素,已经在固定的区域了。你要是修改对象,那么对象就会改变区域,改变后的区域,你删除该对象时候,是找不到的,它默认还户找原来的区域;

这样时间长了,过多的对象不能及时删掉,就会发生内存溢出的现象

2)什么叫做内存泄露,就是有一些对象我们不在用了,但是又没有释放掉,这样就会很占用内存,慢慢的就会发生内存泄露;

举例就是上面1)的例子就可以;

8.         内省 

内省就是JDK提供了对javaBean操作的一些API,这套API称之为内省;

javaBean; 就是一个特殊的java类;

含有getset方法的类,我们称之为javaBean类;也可以当做普通类进行操作;

javaBean的属性名字,是去掉getset后面的单词;如getAge(){};则javaBean的属性名字为age

A.        获取javabean的值,和修改javabean的值的第一种方式;

BeanUtils.setProperty(pt1, "birthday.time", "111");//修改对象里面的值

//获得属性字段的名字;

System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));//得到对象里面的值

//      获取x字段的值;

                   System.out.println(BeanUtils.getProperty(pt1, "x"));

         //      修改x字段的值;

                   BeanUtils.setProperty(pt1, "x", "9");

System.out.println(BeanUtils.getProperty(pt1, "x").getClass().getName());//它的结果是String类型

 

 

B.        获取javabean的值,和修改javabean的值的第二种方式;

通过PropertyUtils这个工具类;

这个PropertyUtils他是不会转变的类型,如这里的9就是整形,

BeanUtils是帮你转换成字符串类型,这里的"111"就是字符串;这个就是两者是有区别;

PropertyUtils.setProperty(pt1, "x", 9);

System.out.println(PropertyUtils.getProperty(pt1, "x"));

System.out.println(PropertyUtils.getProperty(pt1, "x").getClass().getName());//它的结果是integer类型;

 

 

你可能感兴趣的:(程序员)