1.内省
内省(IntroSpector)是Java语言对Bean类属性、事件的一种缺省处理方法。例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值。从而不用通过被private修饰而无法访问的参数变量通过getName/setName来访问name属性,这就是默认的规则。Java中提供了一套API用来访问某个属性的getter/setter方法。
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段, 且方法名符合某种规则。如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object->VO),这些信息在类中用私有字段来存储,如果读取或者设置这些字段的值,则需要通过一些相应的方法来访问。JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。
JavaBean示例
- class Person 此JavaBean的属性为age
- {
- private int x;
- public int getAge()
- {
- return x;
- }
- public void setAge(int age)
- {
- this.x = age;
- }
- }
以下代码是反射的具体应用:
- import java.beans.BeanInfo;
- import java.beans.IntrospectionException;
- import java.beans.Introspector;
- import java.beans.PropertyDescriptor;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.util.Map;
- import org.apache.commons.beanutils.BeanUtils;
- import org.apache.commons.beanutils.PropertyUtils;
- import com.intel.day02.AnnotationTest;
- //用内省的方法来读取x的值
- public class IntroSpector
- {
- public static void main(String[] args) throws Exception
- {
- AnnotationTest.sayHola();
- ReflectPoint pt1 = new ReflectPoint(3 , 5);
- String propertyName = "x";
- Object retVal = getProperty(pt1, propertyName);
- System.out.println("x="+retVal);
- Object value = 7;
- setProperties(pt1, propertyName, value);
- System.out.println("Set:x="+pt1.getX());
- //利用BeanUtils的set和get方法来修改参数
- System.out.println("BeanUtils:x="+BeanUtils.getProperty(pt1, "x"));
- BeanUtils.setProperty(pt1, "x", "8");
- System.out.println("BeanUtilsSet:x="+pt1.getX());
- BeanUtils.setProperty(pt1, "birthday.time", "1987");
- System.out.println("BeanUtils:birthday="+BeanUtils.getProperty(pt1, "birthday.time"));
- //java 1.7新特性
- //Map map = {name:"ajiax",WWID:11454556};
- //BeanUtils.setProperty(map, name, "albert");
- PropertyUtils.setProperty(pt1, "x", 9);
- System.out.println("PropertyUtils:x="+PropertyUtils.getProperty(pt1, "x"));
- }
- private static void setProperties(Object pt1, String propertyName,Object value)
- throws IntrospectionException,IllegalAccessException, InvocationTargetException
- {
- PropertyDescriptor pd1 = new PropertyDescriptor(propertyName,pt1.getClass());
- Method methodSetX = pd1.getWriteMethod();
- methodSetX.invoke(pt1,value);
- }
- private static Object getProperty(ReflectPoint pt1, String propertyName)
- throws IntrospectionException, IllegalAccessException,InvocationTargetException
- {
- /*PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
- Method methodGetX = pd.getReadMethod();
- Object retVal = methodGetX.invoke(pt1);*/
- /*
- * 采用遍历BeanInfo的所有属性的方式来查找和设置某个ReflectPoint对象的x属性。
- * 在程序中把一个类当做JavaBean来看,就是调用IntroSpector.getBeanInfo方法,
- * 得到的BeanInfo对象封装了这个类当做JavaBean看的结果信息。
- *
- * 相比较而言推荐使用上边注释的程序,简介高效
- */
- BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
- PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
- Object retVal = null;
- for(PropertyDescriptor pd : pds)
- {
- if(pd.getName().equals(propertyName))
- {
- Method methodGetX = pd.getReadMethod();
- retVal = methodGetX.invoke(pt1);
- break;
- }
- }
- return retVal;
- }
- }
2.静态导入
mport static静态导入是JDK1.5中的新特性。
一般我们导入一个类都用 import com.....ClassName;而静态导入是这样:import static com.....ClassName.*;这里的多了个static,还有就是类名ClassName后面多了个 .* ,意思是导入这个类里的静态方法。当然,也可以只导入某个静态方法,只要把 .* 换成静态方法名就行了。然后在这个类中,就可以直接用方法名调用静态方法,而不必用ClassName.方法名 的方式来调用。
这种方法的好处就是可以简化一些操作,例如打印操作System.out.println(...);就可以将其写入一个静态方法print(...),在使用时直接print(...)就可以了。
一般我们导入一个类都用 import com.....ClassName;而静态导入是这样:import static com.....ClassName.*;这里的多了个static,还有就是类名ClassName后面多了个 .* ,意思是导入这个类里的静态方法。当然,也可以只导入某个静态方法,只要把 .* 换成静态方法名就行了。然后在这个类中,就可以直接用方法名调用静态方法,而不必用ClassName.方法名 的方式来调用。
这种方法的好处就是可以简化一些操作,例如打印操作System.out.println(...);就可以将其写入一个静态方法print(...),在使用时直接print(...)就可以了。
- <span style="font-size:14px">import static java.lang.Math.*;
- import java.lang.annotation.Annotation;
- import java.lang.reflect.AnnotatedElement;
- import com.intel.day02.AnnotationTest;
- public class StaticImport
- {
- public static void main(String args[])
- {
- System.out.println("Hello Java");
- int x = 1;
- x++;
- System.out.println(x);
- System.out.println(max(3 , 6));
- System.out.println(abs(3 - 6));
- }
- }</span>
特点:
1.只能出现在参数列表的最后
2.位于变量类型和变量名之间,前后有无空格都可以
3.调用可变参数的方法时,编译器为该可变参数隐含
创建一个数组,在方法体中以数组的形式访问可变参数
自动装箱与拆箱
享元模式(英语:Flyweight Pattern)是一种软件设计模式。
它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;
它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存。
通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,
当需要使用时再将它们传递给享元。
通俗解释:有很多个小的对象有很多相同的属性,几把它们封装为一个对象,那些不同的
属性变成方法的参数,称之为外部状态。那些相同的属性抽取出来,称为内部状态。
它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存。
通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,
当需要使用时再将它们传递给享元。
通俗解释:有很多个小的对象有很多相同的属性,几把它们封装为一个对象,那些不同的
属性变成方法的参数,称之为外部状态。那些相同的属性抽取出来,称为内部状态。
- public class VariablePatameter
- {
- public static void main(String[] args)
- {
- System.out.println(add(1,2));
- System.out.println(add(1,2,3));
- System.out.println(add(1,2,3,4));
- AutoBoxingandUnboxing();
- }
- public static int add(int x , int... args)
- {
- int sum = x;
- for(int i = 0 ; i < args.length ; i++)
- {
- sum += args[i];
- }
- System.out.println(sum);
- //增强for循环
- //for(type变量名:变量集合名)
- for(int arg : args)
- {
- sum += arg;
- }
- return sum;
- }
- //自动装箱与拆箱
- public static void AutoBoxingandUnboxing()
- {
- Integer iObj = 3;
- System.out.println(iObj+12);
- Integer i1 = 13;
- Integer i2 = 13;
- System.out.println(i1==i2);//true
- /*
- * i1和i2是同一个对象值为(-128~+127之间时)一旦封装成integer对象后
- * 就会将其缓存起来,放在一个数据池中,当下一次要把另一个变量封装为
- * integer对象时,先去池子中看看有没有相同的对象,有的话直接引用,所以
- * 两个对象指向的是同一个值,节省了内存空间。
- */
- Integer i3 = 137;
- Integer i4 = 137;
- System.out.println(i3==i4);//false
- /*
- * i3和i4不是同一个对象(不在-128~+127之间)
- */
- Integer i5 = Integer.valueOf(3);
- Integer i6 = Integer.valueOf(3);
- System.out.println(i5==i6);//true
- Integer i7 = Integer.valueOf(213);
- Integer i8 = Integer.valueOf(213);
- System.out.println(i5==i6);//false
- String s1 = new String("abc");
- String s2 = new String("abc");
- System.out.println(s1==s2);//false
- }
- }