您的位置:首页 > 编程语言 > Java开发

Java内省和JDK1.5、JDK1.7新特性(高新技术)

2015-05-27 07:57 639 查看

Java内省和JDK1.5、JDK1.7新特性

一、JAVA内省机制

1、内省 IntroSpector

IntroSpector对JavaBean进行操作,那什么是JavaBean呢?看下面这段代码,下面这段代码就是JavaBean

public class Student {

private String name;
private int age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}

public void setAge(int age) {
this.age = age;
}
}


里面的成员属性和成员方法之间有联系,比如有个私有属性名为name,那么这个属性要有两个方法与之对应,public void setName(String name){}、public string  getName(){},符合这种特殊规则的类就叫做JavaBean。JavaBean封装数据,方便传值。

2、使用内省(IntroSpector)对JavaBean进行操作。

public class MyIntroSpectorTest {

public static void main(String[] args) throws  Exception {

Student s=new Student("zhangsan",18);
String propertyName="name";
//通过简单一点的方法
bySimpleMethod(s, propertyName);

String propertyName1="age";
PropertyDescriptor  pd1=new PropertyDescriptor(propertyName1,s.getClass());
Method writeMethod = pd1.getWriteMethod();
Object newValue = writeMethod.invoke(s, 20);
System.out.println(newValue);

//使用复杂一点的方式操作
byGetBeanInfo(s);

}

private static void bySimpleMethod(final Student s, final String propertyName)throws Exception {
//属性描述器
PropertyDescriptor  pd=new PropertyDescriptor(propertyName,s.getClass());
//调用JavaBean的get方法
Method readMethod = pd.getReadMethod();
Object retValue = readMethod.invoke(s);
System.out.println(retValue);
}

private static void byGetBeanInfo(Student s) throws IntrospectionException,IllegalAccessException, InvocationTargetException {
BeanInfo beanInfo = Introspector.getBeanInfo(s.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {

if(propertyDescriptor.getName().equals("name")){

Method method = propertyDescriptor.getReadMethod();
Object retvalue = method.invoke(s);
System.out.println(retvalue);
break;
}
}
}
}


3.BeanUtils的使用

3.1、操作map

3.2、操作javabean

public class MyBeanUtils {

public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Student s=new Student("zhangsan", 18);
//获取属性值
System.out.println(BeanUtils.getProperty(s, "name"));
//设置属性值
BeanUtils.setProperty(s, "age", 8);
System.out.println(	s.getAge());

//BeanUtils操作Map,因为Map的键相当于JavaBean的属性
Map map=new HashMap();
map.put("name", "wangwu");
System.out.println(  BeanUtils.getProperty(map, "name"));

}
}


二、JDK1.5新特性介绍

1.自动包装和解包(Autoboxing and unboxing)

自动装箱:基本类型自动转换为包装类
自动拆包:包装类自动转换为基本类型
代码示例 

  往一个ArrayList中加入一个整数,1.5版本以前的版本写法是: 

  List list = new ArrayList();

  list.add(new Integer(10)); 

  而在1.5版本中可以写为: 

  list.add( 10 );  

  因为,在1.5版本中,对一个整数进行包装,使之成为一个Integer对象(即包装,boxing),然后加入到一个ArrayList中的做法被认为是没有必要的,反之,解包(unboxing)的做法也是没有必要的,这样的代码只是增加了程序的文本长度而已,所以1.5版本支持了自动包装和解包操作,对于bool/Boolean,byte/Byte,double/Double,short/Short,int/Integer,long/Long,float/Float的相应包装/解包操作都进行了支持,从而使代码变得简单。

2.更优化的循环语句(The inhanced for loop)

代码示例 

  一个典型的遍历数组的循环语句,1.5版本以前的写法是:

  for ( Iterator iterator = list.iterator(); iterator.hasNext();){

      Integer n = (Integer)iterator.next();

       ...

  } 

  而在1.5版本中可以写为:

  for ( Integer n : list ){

   ... 

  }

  

  显然1.5版本的写法比以前是大大简化了,但是在需要修改集合,比如删除其中元素时不能采用这种写法。

3.参数可变的方法

当不能确定一个方法的入口参数的个数时,以往版本的Java中,通常的做法是将多个参数放在一个数组或者对象集合中作为参数来传递,1.5版本以前的写法是: 

  int sum(Integer[] numbers){ 

  int nSum = 0; 

  for(int i: numbers) 

     nSum += i;

   return nSum;

  }

  //在别处调用该方法

  sum(new Integer[] {12,13,20});

  

  而在1.5版本中可以写为:

  int sum(Integer... numbers){ 
   int nSum = 0;
  for(int i: numbers) 
  nSum += i; 
  return nSum;
}

  

  //在别处调用该方法 

   sum(12,13,20); 

  显然,1.5版本的写法更为简易,也更为直观,尤其是方法的调用语句,不仅简化很多,而且更符合通常的思维方式,更易于理解。注意:如果方法里面有多个参数,那么可变参数肯定是最后一个

4.枚举

代码示例

  构建一个表示色彩的枚举,并赋值,在1.5版本中可以写为:

  public enum MyColor{ Red, Yellow, Blue } 

  MyColor color = MyColor.Red; 

  for ( MyColor mycolor : MyColor.values() ) 

  System.out.println( mycolor ); 

  以往的Java版本中没有enum关键词,1.5版本中终于加入了进来,这确实是一个令人高兴的改进。此外,enum还提供了一个名为values()的静态方法,用以返回枚举的所有值的集合。所以,以上程序的输出结果是把“Red”、“Yellow”、“Blue”分行输出。 而enum提供的静态方法valueOf()则将以字符串的形式返回某一个具体枚举元素的值,比如“MyColor.valueOf(“Red”)”会返回“Color.Red”。静态方法name()则返回某一个具体枚举元素的名字,比如“MyColor.Red.name()”会返回“Red”。类似的方法还有不少。此外,enum自身还可以有构造方法。

5.静态引用

静态导入:

 格式:import static 包名….类名.方法名;

 可以直接导入到方法的级别

 

 静态导入的注意事项:

  A:方法必须是静态的

  B:如果有多个同名的静态方法,容易不知道使用谁?这个时候要使用,必须加前缀。由此可见,意义不大,所以一般不用,但是要能看懂。

import static java.lang.Math.abs;
import static java.lang.Math.pow;
import static java.lang.Math.max;
import static java.util.ArrayList.add;//错误,因为add方法是非静态的

public class StaticImportDemo {
public static void main(String[] args) {
// System.out.println(java.lang.Math.abs(-100));
// System.out.println(java.lang.Math.pow(2, 3));
// System.out.println(java.lang.Math.max(20, 30));
// 太复杂,我们就引入到import

// System.out.println(Math.abs(-100));
// System.out.println(Math.pow(2, 3));
// System.out.println(Math.max(20, 30));
// 太复杂,有更简单

//System.out.println(abs(-100));
System.out.println(java.lang.Math.abs(-100));
System.out.println(pow(2, 3));
System.out.println(max(20, 30));
}

public static void abs(String s){
System.out.println(s);
}
}


6、泛型(Generics) 

6.1、泛型概述

 泛型定义:是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递   
格式:

   <数据类型>、此处的数据类型只能是引用类型。

    好处:

  A:把运行时期的问题提前到了编译期间

  B:避免了强制类型转换(ClassCastExceptions)

  C:优化了程序设计,解决了黄色警告线

    泛型在哪些地方使用呢?

    看API,如果类,接口,抽象类后面跟的有<E>就说要使用泛型。一般来说就是在集合中使用。注意:泛型可以用在类上,还有泛型方法,泛型接口。

6.2泛型类

泛型类:把泛型定义在类上

<span style="font-weight: normal;">public class ObjectTool<T> {
private T obj;

public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}</span>

泛型类的测试

<span style="font-weight: normal;"> public class ObjectToolDemo {
public static void main(String[] args) {

ObjectTool<String> ot = new ObjectTool<String>();
// ot.setObj(new Integer(18)); //这个时候编译期间就过不去
ot.setObj(new String("张三"));
String s = ot.getObj();
System.out.println("姓名是:" + s);

ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
// ot2.setObj(new String("李四"));//这个时候编译期间就过不去
ot2.setObj(new Integer(27));
Integer i = ot2.getObj();
System.out.println("年龄是:" + i);
}
}</span>


6.3泛型方法

泛型方法:把泛型定义在方法上

<span style="font-weight: normal;">public class ObjectTool {
public <T> void show(T t) {
System.out.println(t);
}
}</span>

泛型方法测试

<span style="font-weight: normal;">public class ObjectToolDemo {
public static void main(String[] args) {
// 定义泛型方法后
ObjectTool ot = new ObjectTool();
ot.show("hello");
ot.show(100);
ot.show(true);
}
}</span>


6.4泛型接口

<span style="font-weight: normal;">泛型接口:把泛型定义在接口上
</span>
<pre name="code" class="java"><span style="font-weight: normal;">public interface Inter<T> {
public abstract void show(T t);
}</span>

<span style="font-weight: normal;">泛型接口实现类:
//第一种情况:知道是什么类型
public class InterImpl implements Inter<String> {
@Override
public void show(String t) {
System.out.println(t);
}
}</span>
//第二种情况:还不知道是什么类型的

public class InterImpl<T> implements Inter<T> {
@Override
public void show(T t) {
System.out.println(t);
}

}



泛型接口测试:
<span style="font-weight: normal;">public class InterDemo {
public static void main(String[] args) {
// 第一种情况的测试
// Inter<String> i = new InterImpl();
// i.show("hello");

// // 第二种情况的测试
Inter<String> i = new InterImpl<String>();
i.show("hello");

Inter<Integer> ii = new InterImpl<Integer>();
ii.show(100);
}
}</span>


6.5泛型高级(通配符)

?:任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E:向下限定,E及其子类
? super E:向上限定,E极其父类

示例代码:

<span style="font-weight: normal;">class Animal {}

class Dog extends Animal {}

class Cat extends Animal {}

public class GenericDemo {
public static void main(String[] args) {
// 泛型如果明确的写的时候,前后必须一致
Collection<Object> c1 = new ArrayList<Object>();
// Collection<Object> c2 = new ArrayList<Animal>();
// Collection<Object> c3 = new ArrayList<Dog>();
// Collection<Object> c4 = new ArrayList<Cat>();

// ?表示任意的类型都是可以的
Collection<?> c5 = new ArrayList<Object>();
Collection<?> c6 = new ArrayList<Animal>();
Collection<?> c7 = new ArrayList<Dog>();
Collection<?> c8 = new ArrayList<Cat>();

// ? extends E:向下限定,E及其子类
// Collection<? extends Animal> c9 = new ArrayList<Object>();
Collection<? extends Animal> c10 = new ArrayList<Animal>();
Collection<? extends Animal> c11 = new ArrayList<Dog>();
Collection<? extends Animal> c12 = new ArrayList<Cat>();

// ? super E:向上限定,E极其父类
Collection<? super Animal> c13 = new ArrayList<Object>();
Collection<? super Animal> c14 = new ArrayList<Animal>();
// Collection<? super Animal> c15 = new ArrayList<Dog>();
// Collection<? super Animal> c16 = new ArrayList<Cat>();
}
}</span>


6.6泛型擦除
因为泛型的限定是给编译器看的,在运行的时候泛型就没有了,尽管你限定了泛型,但是我拿到类的字节码文件,一样可以得到类中所有类的元素。

三、JDK7新特性

关于JDK7的新特性,我所知道的,全部包含在下面的代码中了。
1、二进制字面量

        2、数字字面量可以出现下划线

3、switch 语句可以用字符串

4、泛型简化

        5、 try-with-resources 语句

public class Demo {
public static void main(String[] args) {
// 二进制字面量
int x = 0b100101;
System.out.println(x);
// 数字字面量可以出现下划线
int y = 1_1123_1000;
// 不能出现在进制标识和数值之间
int z = 0x111_222;
// 不能出现在数值开头和结尾
int a = 0x11_22;
// 不能出现在小数点旁边
double d = 12.3_4;
// switch 语句可以用字符串
// 泛型简化
ArrayList<String> array = new ArrayList<>();
// 异常的多个catch合并
method();
}

private static void method() {
// try-with-resources 语句
// try(必须是java.lang.AutoCloseable的子类对象){…}
try {
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
fw.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
}

// 改进版的代码
try (FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");) {
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

好啦今天先写到这里。。。。。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: