java加强之jdk1.5新特性

 

 

 jdk1.5新特性:

1、静态导入

package jdk_5new;
/**
 * 静态导入是jdk1.5新特性,可以直接导入类中的静态方法
 */
import static java.lang.Math.max;
import static java.lang.Math.abs;

public class StaticImport {
 
 public static void main(String[] args) {
  System.out.println(Math.max(3,8));
  System.out.println(Math.abs(-21));
 }

}

2、可变参数(参数个数不确定)

      oveload与override(当父类一个方法定义为private,子类中定义一个与之相同的方法,算不算是重写呢?不算!算是一个全新的方法)

package jdk_5new;

/**
 * @author Administrator
 *
 */
public class VariableParameter {
 
 public static void main(String[] args) {
   System.out.println(add(2,3));
   System.out.println(add(2,3,4));
 }
 
 public static int add(int x, int...args){
  int sum = x;
  for(int i=0;i<args.length;i++){
   sum = sum+args[i];
  }
  return sum;
 }
}

 

3、增强的for循环

package jdk_5new;

public class ExtendedFor {
 public static void main(String[] args) {
  System.out.println(add(2, 3));
  System.out.println(add(2, 3, 4));
 }

 public static int add(int x, int... args) {
  int sum = x;
  for (int arg:args) {
   sum = sum + arg;
  }
  return sum;
 }
}

 

4、自动装箱与拆箱(-128~127 享元模式 flyWeight)

package jdk_5new;

public class AutoBox {
 public static void main(String[] args) {
  //自动装箱
  Integer num = 3;
  
  //自动拆箱
  int sum = num +2;
  System.out.println(sum);
  
  Integer num1 = 13;
  Integer num2 = 13;
  Integer num3 = 128;
  Integer num4 = 128;
  
  String s1 = new String("abc");
  String s2 = new String("abc");
  
  System.out.println("num1 == num2:"+(num1 == num2));
  System.out.println("num3 == num4:"+(num3 == num4));
  
  //s1 == s2 比较的是两个对象的地址
  System.out.println("s1 == s2 :"+(s1 == s2));
  //这里String的equals方法被重写了,比较的是两个对象的值
  System.out.println("s1.equals(s2): "+s1.equals(s2));
 }
 
 /**
  * 装箱如果数字在-128~127的这些数字,一旦被装箱成Integer对象之后,就会被缓存起来
  * 缓冲在一个池里面,到下次如果遇到又要把它封装成对象的时候,先看池子里面有没有,
  * 如果有直接从池里面拿出来。因为我觉得小的整数用的频率会非常高,并且经常不会改变。
  * 所以就 用一个池存起来,实现重用。
  * (享元模式)经常用到的小对象,不会每次都创建!而是放到一个对象池里面。
  */
 
}

 

5、枚举

     为什么要有枚举?问题:要定义星期几或性别的变量,该怎么定义?枚举就是让某个类型的变量只能为若干个固定值中的一个,否则编译

器就会报错。

package jdk_5new;

public class Enum_1 {
 public static void main(String[] args) {
  
  //编译时就发现你输入的值不合法
  Week WeekDay = Week.FRI;
  //打印一个对象,其实就是打印他的toString
  
  System.out.println(WeekDay);
  System.out.println(WeekDay.nextDay());
  
  //通过匿名内部类的方式将众多的if...else分解到不同的方法中。
  Week2 week2 = Week2.MON;
  System.out.println(week2);
  System.out.println(week2.nextDay());
 }
}

 

package jdk_5new;

public class Week {

 private Week(){
  
 }
 
 public final static Week SUN = new Week();
 public final static Week MON = new Week();
 public final static Week TUE = new Week();
 public final static Week WEN = new Week();
 public final static Week THU = new Week();
 public final static Week FRI = new Week();
 public final static Week SAT = new Week();
 
 public Week nextDay(){
  if(this == SUN){
   return MON;
  }else if(this == MON){
   return TUE;
  }else if(this == TUE){
   return WEN;
  }else if(this == WEN){
   return THU;
  }else if(this == THU){
   return FRI;
  }else if(this == FRI){
   return SAT;
  }else if(this == SAT){
   return SUN;
  }else
   return MON;
 }
 
 /**
  * 如果没有重写这个toString方法,打印就会有问题。打印Week对象时,会调用这个方法。
  * 打印一个对象,就是打印他的toString
  */
 public String toString(){
  if(this == SUN){
   return "今天是星期天!";
  }else if(this == MON){
   return  "今天是星期一!";
  }else if(this == TUE){
   return  "今天是星期二!";
  }else if(this == WEN){
   return  "今天是星期三!";
  }else if(this == THU){
   return  "今天是星期四!";
  }else if(this == FRI){
   return  "今天是星期五!";
  }else{
   return  "今天是星期六!";
  }
 }
}

 

6、反射(反射不是jdk1.5的新特性,而是jdk1.2就开始有了)

package jdk_5new;

import java.lang.reflect.*;
import java.util.Arrays;

/**
 *
 * @author Administrator Class---->代表一种什么样的事物? Person person1 = new Person();
 *         Person person2 = new Persion();
 *
 *         Class cls1 = new Class()??? 没有这种方法, Class cls2 = ;
 *
 *         Class 实例对象代表内容里的一份字节码
 *
 *         Class cls1 = Date.class //字节码1 Class cls2 = Person.class //字节码2
 *
 *         getClass(); 得到这个类的字节码 Class.forName("java.lang.String");
 *
 *         得到一个类的字节码有两种方式 : 第一种:这个类的字节码已经加载到内存中,此时直接返回就可以了;
 *         第二种:虚拟机中还没有这个类的字节码,于是用类加载器去加载。
 *         加载后就把这个类的字节码缓存起来,同时用Class.forName()这个方法 返回刚才加载的字节码
 *
 *         如何得到各个字节码对应的实例对象?(Class类型) 有三种方法: 1、类名.class,如 System.class
 *         2、实例名.class,如 new Date().getClass 3、Class.forName("类名"),如
 *         Class.forName("java.lang.String");
 *         反射的时候最常用的是第三种,因为在写源程序的时候,并不知道要创建实例的类的名称,
 *         而是在运行的时候才将类的类型传进来。比如从配置文件里面读取。
 *
 */
public class ClassDemo {
 public static void main(String[] args) throws Exception {

  /**
   * Class 类的实例表示正在运行的 Java 应用程序中的类和接口。 枚举是一种类,注释是一种接口。每个数组属于被映射为 Class
   * 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java
   * 类型8个(boolean、byte、char、short、 int、long、float 和 double)和关键字 void 也表示为
   * Class 对象。
   */
  System.out.println(void.class);
  System.out.println(int.class);

  /**
   * 用各各方式,得到的是内存中同样一份字节码
   */
  String str1 = "abc";
  Class cls1 = str1.getClass();
  Class cls2 = String.class;
  Class cls3 = Class.forName("java.lang.String");

  System.out.println(cls1 == cls2);
  System.out.println(cls2 == cls3);
  System.out.println(cls1 == cls3);

  // isPrimitive() 判定指定的 Class 对象是否表示一个基本类型。
  System.out.println(cls1.isPrimitive()); // false
  System.out.println(int.class.isPrimitive()); // true
  System.out.println(int.class == Integer.class); // false
  /*
   * Object.TYPE 表示所包装的那个基本类型的字节码 static Class<Integer> TYPE 表示基本类型 int 的
   * Class 实例。
   */
  System.out.println(int.class == Integer.TYPE); // ture
  System.out.println(int[].class);
  System.out.println(int[].class.isPrimitive());
  System.out.println(Array.class);
  System.out.println(int[].class.isArray());
  // 总之,只要是在程序中出现的类型,都有各自的Class实例对象,例如int[],void

  // new String(new StringBuffer("abc"))
  Constructor cons1 = String.class.getConstructor(StringBuffer.class);
  String str = (String) cons1.newInstance(new StringBuffer("abc"));

  // Field 成员变量
  ReflectPoint reflectp1 = new ReflectPoint(3, 5);
  ReflectPoint reflectp2 = new ReflectPoint(4, 8);
  // FieldY不是对象上的变量,而是类上的变量,它去取某个对象上对应的值
  Field fieldY = ReflectPoint.class.getField("y");
  System.out.println(fieldY.get(reflectp1));
  System.out.println(fieldY.get(reflectp2));

  // 对私有成员的反射取值
  Field fieldX = ReflectPoint.class.getDeclaredField("x");
  // 暴力反射
  fieldX.setAccessible(true);
  System.out.println(fieldX.get(reflectp2));

  changeStrValue(reflectp1);
  System.out.println(reflectp1);

  // 成员方法反射Method
  Method methodCharAt = String.class.getMethod("charAt", int.class);

  // invoke 列车司机把列车停下来,但并不是司机真正把它停下来。而是列车员踩刹车,
  // 给列车发信号,列车自已开启自己的制动系统让自己停下来。所以只有火车自己才更清楚该
  // 怎么停下来!String也是,String调用自己的invoke方法截取字符
  System.out.println(methodCharAt.invoke(str1, 1));

  // 如果第一个参数为null,意味着这个method为静态方法
  // System.out.println(methodCharAt.invoke(null,1));

  // 1、直接用静态代码的方式调用main
  TestArguments.main(new String[] { "111", "222", "333" });
  // 2、用反射的方式调用main,为什么要用反射的方式调用?我不知道调用哪个类的main方法,而是以参数传入
  String startingClassName = args[0];
  Method mainMethod = Class.forName(startingClassName).getMethod("main",
    String[].class);
  // jdk1.4不把数组而是一个参数,而是当成三个参数
  mainMethod.invoke(null, new Object[] { new String[] { "aaa", "bbb",
    "ccc" } });
  // 哥们,我给你的是一个Object,而不是数组,不要给我拆包啊
  mainMethod.invoke(null, (Object) new String[] { "aaa", "bbb", "ccc" });

  // 数组的Class类型
  int[] a1 = new int[3];
  int[] a2 = new int[4];
  int[][] a3 = new int[2][3];
  String[] a4 = new String[3];
  String[] a5 = new String[] { "a", "b", "c" };
  int[] a6 = new int[] { 1, 2, 3 };
  Integer[] a7 = new Integer[] { 1, 2, 3 };
  System.out.println(a1.getClass() == a2.getClass());
  System.out.println(a3.getClass().getName());
  System.out.println(a1.getClass().getSuperclass().getName());

  // 打印数组
  System.out.println(Arrays.asList(a5));
  /*
   * 1.4中没有可变参数,asList中只能是对象(Object)类型,于是自动匹配1.5的asList asList(T...a)
   * 这种可变参数的形式,虚拟机就会把int数组当成是一个参数
   */
  System.out.println(Arrays.asList(a6));
  System.out.println(Arrays.asList(a7));

  int []a8 = new int[]{1,2,3,4,5};
  printObject(a8);
  printObject("abc");
  
  //Object里面可以放不同类型的数据哦!
  Object[] a9 = new Object[]{"a",1};
  System.out.println(a9[0].getClass().getName());
  System.out.println(a9[1].getClass().getName());
 }

 /**
  *
  * @param obj
  * @throws Exception
  *             需求:通过反射将一个对象中的成员变量值换掉
  */
 public static void changeStrValue(Object obj) throws Exception {
  Field[] fields = obj.getClass().getFields();
  for (Field field : fields) {
   // 相同的Class类型(字节码)都是一份,比较用"=="
   if (field.getType() == String.class) {
    String oldStr = (String) field.get(obj);
    String newStr = oldStr.replace('b', 'a');
    field.set(obj, newStr);
   }
  }
 }

 // 数组也是一个对象,是一个特殊的对象
 public 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);
  }
 }

}

// 自己写程序,调用人家的main方法
class TestArguments {
 public static void main(String[] args) {
  for (String arg : args) {
   System.out.println(arg);
  }
 }
}

 

7、泛型  泛型在函数体本身不明确其参数类型,而是在创建对象的时候指定参数具体指定的类型。这样就可以在函数内部不用强制类型转换,并且将

可能在运行阶段出现的问题在编译阶段就暴露出来。

package generic;

import java.io.Serializable;
import java.util.*;

/**
 * 泛型类型的确定:
 * 1、输入参数什么类型就是什么类型
 * 2、多个输入参数不同类型时,取多个参数的公共父类的类型
 * 3、有返回值(并且有显示接收返回值)泛型变量值以返回值类型为准。
 * @author Administrator
 *
 * @param <T>
 */
public class GenericTest2{
 public static void main(String[] args) {
  Demo<String> d = new Demo<String>();
  // 泛型的真实类型,取他们共同的父类
  //类型变量根据输入参数确定的例子
  add(3, 5);
  add(3.5, 5);
  add(3, "abc");
  Object obj = "abc";
  //接收返回值的是什么类型我就返回什么类型
  //泛型变量根据返回值类型确定的例子
  String str = autoConvert(obj);
  //此时T为Integer
  //Integer n = autoConvert(obj);
  //此时T没指定返回原始类型
  System.out.println(autoConvert(obj).getClass());
 }

 public static <M> M add(M x, M y) {
  return null;
 }
 
 public static <T> T autoConvert(Object obj){
  return (T)obj;
 }
 
 public static <T> void fillArray(T[]a,T obj){
  for(int i=0;i<a.length;i++){
   a[i] = obj;
  }
 }
 
 //Collection<Object> != Collection<Integer>
 //泛型是不识别父类子类的,严格相等才是相等的。
                                    //这里的?是指Collection里面可以放什么类型的元素
 public static void printCollection(Collection <?> collection){
  for(Object obj:collection){
   System.out.println(obj);
  }
 }
 
 //任意类型打印,用?也可以,用类型变量<T>也行,但T更灵活
 public static <T>void printCollection2(Collection <T> collection,T t){
  for(Object obj:collection){
   System.out.println(obj);
  }
  collection.add(t);
 }
 
 public static <T> void copy1(Collection<T> c,T []src){
  
 }
 
 public static <T> void copy2(T[] dest,T[] src ){
  
 }
 
}

// 泛型的类型只能引用类型作为实际参数,而不能用基本类型
class Demo<T extends Serializable> {

}

 

8、注释 annotation

package annotation;

import java.util.Arrays;

@ItcastAnnotation(value = "abc", arrayAttr = 2, annotationAttr = @MetaAnnotation("zhougang"))
public class AnnotationTest {

 @SuppressWarnings("deprecation")
 @ItcastAnnotation(value = "abc", arrayAttr = { 0 })
 public static void main(String[] args) {
  System.runFinalizersOnExit(true);
  if (AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)) {
   ItcastAnnotation annotation = (ItcastAnnotation) AnnotationTest.class
     .getAnnotation(ItcastAnnotation.class);
   ItcastAnnotation annotation1 = (ItcastAnnotation) AnnotationTest.class
     .getAnnotation(ItcastAnnotation.class);
   // 注解
   System.out.println(annotation);
   System.out.println(annotation.color());
   System.out.println(annotation.value());
   System.out.println(annotation.arrayAttr().length);
   System.out.println(annotation.lamp().nextLamp().name());
   System.out.println(annotation.annotationAttr().value());
  }
 }
}

 

  

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值