JAVA高级特性(一)

----------------------------------debug------------------------------
可以在templates中配置模板

f5 step into跳入(进入方法里面)
f6 step over进过(一步一步走。) 
f7  step return 跳出

drop to frame跳到当前方法的第一行代码,后退
resume跳到下一个断点执行,如果没有下一个段点,则执行完程序
watch 观察变量(或表达式)的值
------------------------------------------------------
String 是final型的 不能相加
静态代码快只执行一次(类加载时执行),比较两个对象是否为同一个字节码,可以使用==来比较(因为同一个字节码只有一份,如果相等则地址必须相同。
----------------------------junit------------------------------------  
junit:运行这个类的全部的方法,点击类运行,

注解:
@Test:
写一个类,定义一个方法,该方法必须public,返回值为void,不能是static,
在方法上面加注解 @Test  按下Ctrl+1, 导入jar包,导包、

需要初始化
@BeforeClass  static的  最先执行  1次
   @Before 多少个方法执行多少次
       代码
  @After 多少个方法执行多少次
需要释放资源
@AfterClass  static的  最后执行  1次

断言Assert.assertEquals("1", "1");期望的和返回的一样就是true,
-------------------------新特性jdk5.0---------------------------------------
自动装箱和拆箱:
基本类型->对象类型   比如    int ->Integer
自动拆箱  反之
 int i = 1;  //(对应Integer对象)
                //装箱 i这么一个基本类型的数,可以赋值给Integer型的变量?因为java虚拟机自动取出i的值,放到Integer对象中,然后把对象给j。
  Integer j = i; 
                //拆箱 怎么把对象赋给基本类型呢?因为自动取出对象的值,在赋给k(赋值的是对象封装的值)
  int k = j; 
-----------------------------------------------------------
可变参数

传入多个参数
        List list = Arrays.asList("a","b","c","d");
 System.out.println(list.size());

注意的问题:可变参数在传的时候可以直接传数组
        String[] arr = new String[]{"a","b"};
        List list = Arrays.asList(arr);
       System.out.println(list.size());

//注意的问题:传基本数据类型数组时要千万小心,会当成一个对象传进去,打印的是地址,要是对象Integer
  int arr[] = {1,2,3};  //Integer arr[] = {1,2,3};
  list = Arrays.asList(arr);
  System.out.println(list);
  }

 public static void sum(int ... nums){
  //拿到可变参数,当成数组用即可
  int sum = 0;
  for(int num : nums){
   sum += num;
  }
  System.out.println(sum);
 }
-----------------------------------------------------------
增强for注意的问题:增强for只适合取数据,不要用它去修改数组或集合中的数据

//常见应用:集合
  List list = new ArrayList();
  list.add("a");//把1变成对象,add的是1对应的对象  装箱
  list.add("b");
  list.add("c");
  
  Iterator it = list.iterator();
  while(it.hasNext()){   
   int m = (String)it.next();         //拆箱
  }

        for(Iterator iter=list.iterator(); iter.hasNext(); ) {
   String str = (String) iter.next();
   System.out.println(str);
        }
//增强for循环
       for(Object obj : list) {
    String str = (String) obj;
   System.out.println(str);
         }
-------------------------------------------------------------
增强for注意的问题:增强for只适合取数据,不要用它去修改数组或集合中的数据

迭代map
hashMap:无序
treeMap:传比较器,才有序麻烦
LinkedHashMap:有序~~~~~~~~~~~~~~~~~

                Map m = new HashMap();
         m.put("1", "aa");
  m.put("2", "bb");
通过key得到value:
  Set ks = m.keySet();
  Iterator it = ks.iterator();
  while (it.hasNext()) {//传统方式
   String key = (String) it.next();
   String value = (String) m.get(key);
   System.out.println(key + "=" + value);
  }
//for循环
  for (Object obj : ks) {
   String s = (String) obj;
   String v = (String) m.get(s);
   System.out.println(s + "=" + v);
  }
通过Map.Entry得到键和值:超级重要  jstl也用这种方式
  Set set = m.entrySet();
  it = set.iterator();
  while (it.hasNext()) {//传统方式
   Map.Entry en = (Entry) it.next();
   String key = (String) en.getKey();
   String value = (String) en.getValue();
   System.out.println(key + "=" + value);
  }
//for循环
  for (Object obj : m.entrySet()) {
   Map.Entry me = (Entry) obj;
   String key = (String) me.getKey();
   String value = (String) me.getValue();
   System.out.println(key + "=" + value);
  }

---------------------------------------------------------------
反射:重要,用在框架上,反射的真个类
private:私有的外界无法访问到,但是反射能做到强行执行。不是public的都可以执行。Pubic也可以执行
装载类3种
//装载类1
Class clazz1 = Class.forName("cn.itcast.reflect.Person");  
//2.
Class clazz2 = Person.class;  
//3.
Class clazz3 = new Person().getClass();

反射构造方法//public Person(String name){}
         Class clazz = Class.forName("cn.itcast.reflect.Person");
  Constructor c = clazz.getConstructor(String.class);//类型来分辨
  Person p = (Person) c.newInstance("xxx");//先调用构造函数
  System.out.println(p.getName());

解剖私有//private Person(List list[]){}
                Class clazz = Class.forName("cn.itcast.reflect.Person");
  Constructor c = clazz.getDeclaredConstructor(List[].class);
  c.setAccessible(true);  //暴力反射
  Person p = (Person) c.newInstance((Object)new ArrayList[4]);
  System.out.println(p);


字段//设置name属性的值
              Person p = new Person();
  Class clazz = Class.forName("cn.itcast.reflect.Person");
  Field f = clazz.getDeclaredField("name");
  f.setAccessible(true);
  f.set(p, "xxx");

反射获取name属性的值
                Class clazz = Class.forName("cn.itcast.reflect.Person");
  Field f = clazz.getDeclaredField("name");
  f.setAccessible(true);
  String name = (String) f.get(p);
  System.out.println(name);


方法//public void xx1()
               Class clazz = Class.forName("cn.itcast.reflect.Person");
  Method method = clazz.getMethod("xx1", null);
  method.invoke(p, null);//调用方法运行:指定的方法p

private的//private int[] xx1(List list)
        Person p = new Person();
  Class clazz = Class.forName("cn.itcast.reflect.Person");
  Method method = clazz.getDeclaredMethod("xx1", List.class);
  method.setAccessible(true);
  int[] arr = (int[]) method.invoke(p, new ArrayList());

静态方法


main方法
                 Class clazz = Class.forName("cn.itcast.reflect.Person");
  Method method = clazz.getMethod("main",String[].class);
  //第一种method.invoke(null, new Object[]{new String[]{"1","2"}});
  method.invoke(null, (Object)new String[]{"1","2"});

---------------------------------------------
内省:内省的是对象,操作反射bean的属性。框架用的
用途:页面注册、,经过框架,封装到bean里去,比如username,有这个字段就帮他封装到bean里去。
字段:name,age
属性:set和get方法
默认都有一个object的getClass()属性。因为都是它的子类有,会继承它。

introspector的API
getBeanInfo是封装bean的所有属性
getPropertyDescriptors()属性描述器的数组
getEeadMethod()读取
getWriteMethod()赋值

操作bean的属性
  Student bean = new Student();
  //得到bean的所有属性
  BeanInfo info = Introspector.getBeanInfo(Student.class);
  //得到bean的所有属性描述器
  PropertyDescriptor pds[] = info.getPropertyDescriptors();
  for(PropertyDescriptor pd : pds){  //name
   String propertyName = pd.getName();
   if(propertyName.equals("name")){
    Method  m = pd.getWriteMethod();  //setName(String name)
    m.invoke(bean, "flx");
   }
  }

操作bean的指定属性: age       
  PropertyDescriptor pd = new PropertyDescriptor("age",bean.getClass());
  Method method = pd.getWriteMethod();  //setAge(int age)
  method.invoke(bean, 12);
  //通过内省获取bean的age属性
  method = pd.getReadMethod(); //  getAge()
  int age = (Integer) method.invoke(bean, null);
---------------------------------------------
beanUtils框架是Apache的
导入jar:最短的,
  log4j:需要log4j的commons-logging.jar的支持
使用beanutils框架操作bean属性,会自动对数据进行转换,这仅于8种基本数据类型

基本操作
                Student bean = new Student();
  BeanUtils.setProperty(bean, "name", "flx");
  String name = BeanUtils.getProperty(bean, "name");
较高级的操作
                BeanUtils.setProperty(bean, "age", "12");  //beanutils框架会自动对数据进行转换,这仅于8种基本数据类型
  System.out.println(bean.getAge()+1);
高级的操作
注册日期转换器ConvertUtils.register(new Converter(){
   public Object convert(Class type, Object value) {
    if(value==null){
     return null;
    }
    if(!(value instanceof String)){
     throw new ConversionException("只支持字符串的转换");
    }
    String date = (String) value;
    if(date.trim().equals("")){
     return null;
    }
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    try {
     return df.parse(date);
    } catch (ParseException e) {
     throw new ConversionException(e);
    }
   }
},Date.class)
BeanUtils.setProperty(bean, "birthday", "");  //beanutils框架会自动对数据进行转换,(对象,属性名,属性值) //设置对象属性值
  System.out.println(bean.getBirthday());  //date.toString()老外的格式

------------------------------------------------------
枚举:构造函数要private的。因为不能new
1.解决的问题,类的某个字段或方法传入的参数不能为任意值,必须为某一系列限定的取值
2. 解决问题的办法
办法1:在set方法中判断,如果不符合取值,抛一个运行时异常
public void setGrade(String grade) {
  //加判断
  if(!grade.matches("[ABCDE]")) {
   throw new RuntimeException("参数非法");
  }
  this.grade = grade;
}
办法2:自定义一个Grade类,将构造方法私有,对外提供5个变量记住类的实例
public class Grade1 {
 // 不让别人随便new对象
 private Grade1() {}
 //提供一组取值
 public final static Grade1 A = new Grade1();
 public final static Grade1 B = new Grade1();
 public final static Grade1 C = new Grade1();
 public final static Grade1 D = new Grade1();
 public final static Grade1 E = new Grade1();
}
办法3:在jdk5中定义了枚举,用于解决这类问题
public enum Grade2 {
 A,B,C,D,E;
}
3.所有的枚举都是Enum的子类,常用方法
Grade3 grade = Grade3.C;
 // 获得枚举的名称
 String name = grade.name();
 System.out.println(name);
 // 获得枚举的次序
 int ordinal = grade.ordinal();
 System.out.println(ordinal);
 // 通过名字拿枚举对象
 Grade3 g = Grade3.valueOf("D");
 System.out.println(g.name());
 // 获得所有的枚举
 Grade3[] values = Grade3.values();
 System.out.println(values[1].name());
4.枚举就是一个普通的java类,可以有方法、属性和构造方法
定义属性value记住枚举的值
public enum Grade4 {
 A("90-100"),B("80-89"),C("70-79"),D("60-69"),E("0-59");
 private String value;
 private Grade4(String value) {
  this.value = value;
 }
 public String getValue() {
  return value;
 }
 public void setValue(String value) {
  this.value = value;
 }
 
}
定义方法toLocaleString返回中文格式
public enum Grade5 {
 // 匿名内部类
 A("90-100"){
  public String toLocaleString() {
   return "优";
  }
 }
 ,B("80-89"){
  public String toLocaleString() {
   return "良";
  }
 }
 ,C("70-79"){
  public String toLocaleString() {
   return "中";
  }
 }
 ,D("60-69"){
  public String toLocaleString() {
   return "差";
  }
 }
 ,E("0-59"){
  public String toLocaleString() {
   return "不及格";
  }
 };
 private String value;
 private Grade5(String value) {
  this.value = value;
 }
 public String getValue() {
  return value;
 }
 public void setValue(String value) {
  this.value = value;
 }
 
 // 一个方法在没有想好怎么实现的时候,就声明为抽象方法,留给具体的子类去实现
 public abstract String toLocaleString();
}

编写一个关于星期几的枚举WeekDay,设计一个方法返回中文格式的星期
 MON("星期一"),TUE("星期二"),WED("星期一"),THU("星期一"),FRI("星期一"),SAT("星期一"),SUN("星期一");
 private String value;
 private WeekDay(String value){
  this.value = value;
 }
 public String toLocaleString(){
  return value;
 }

-------------------------------------------------------
泛型:
1.泛型作用:提高容器的安全性,在编译阶段检查向集合中存储对象的类型。编译器在编译完带有泛型完成带有泛型的Java文件后,生成的class文件中将不再带有泛型信息,以保证程序的运行效率。
2. 好处:使用泛型的集合,在迭代的时候不用强转。将运行时可能发生的异常,转变为编译时错误。
3. 一旦使用泛型,两边的类型就必须一致,否则会出错。只在一边指定泛型不会报错。泛型的类型必须指定为引用数据类型,不能为基本数据类型
ArrayList<String> al = new ArrayList<Object>();
String str = al.get(1);
如果可以,明明集合里存的是Object,取出来的却都是String,不可能
ArrayList<Object> al = new ArrayList<String>();
al.add(new Student());
如果可以,明明集合只要String, 但是我们什么都能存,不可能

4. 为了向后兼容,可以只在一边指定泛型
ArrayList al = new ArrayList<String>();
相当于:
run(new ArrayList<String>());
public static void run(ArrayList al) {
  
}
---------------------------------------------
ArrayList<String> al = new ArrayList();
相当于: 
doXX(new ArrayList());
public static void doXX(ArrayList<String> al) {
  
}

5. 自定义泛型
泛型必须先定义,再使用
泛型到底是什么类型,取决去调用者的指定
静态的变量不能使用泛型,因为人家会用类名.变量名的方式调用,没有机会指定泛型
方法中定义的泛型,必须在返回值前面先声明
泛型的定义决定了它作用范围内所有的该泛型类型的一致性

在类上定义泛型,作用与所有成员
public class Boy<T> {
 private T t;
 public void eat(T t) {
  
 }
}

在方法上定义泛型,作用于当前方法
public <T> void play(T t) {
  
}
public static<T> void run(T t) {
  
}

类的静态属性不能使用泛型
private static T t1; //会报错,类名.变量名的方式调用,没有机会指定泛型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值