JDK5新特性

自动装箱与拆箱

基本类与包装类对应关系:
在这里插入图片描述
包装类型转基本类型:
在这里插入图片描述
基本类型转包装类型:
在这里插入图片描述

自动装箱,自动拆箱:

Integer i = 11;//自动装箱,实际上执行了Integer i = Integer.valueOf(11);
int t = i;//自动拆箱,实际上执行了 int t = i.intValue();

参考:https://baijiahao.baidu.com/s?id=1579601823966912111&wfr=spider&for=pc

枚举

package pers.terry.demo.jdk.jdk5;

public class EnumDemo {
    // 无带参构造
    public enum TrafficLamp {
        RED, GREEN, YELLW;
    }

    // 提供带参构造
    public enum TrafficLamp2 {
        RED(30), GREEN(40), YELLW(5);
        private int time;

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

        public int getTime() {
            return time;
        }
    }

    // 提供带参构造,并有抽象方法
    public enum TrafficLamp3 {
        RED(30) {
            @Override
            public TrafficLamp3 nextLamp() {
                return TrafficLamp3.GREEN;
            }
        },
        GREEN(40) {
            @Override
            public TrafficLamp3 nextLamp() {
                return TrafficLamp3.YELLW;
            }
        },
        YELLW(5) {
            @Override
            public TrafficLamp3 nextLamp() {
                return TrafficLamp3.RED;
            }
        };
        private int time;

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

        public int getTime() {
            return time;
        }

        // 提供一个抽象方法,用于获取下个灯
        public abstract TrafficLamp3 nextLamp();
    }

    public static void main(String[] args) {
        System.out.println(TrafficLamp.GREEN);
        System.out.println(TrafficLamp2.GREEN);
        System.out.println(TrafficLamp2.GREEN.getTime());
        System.out.println(TrafficLamp3.GREEN);
        System.out.println(TrafficLamp3.GREEN.nextLamp());
    }
}

参考:https://blog.csdn.net/kongqis/article/details/47315653

静态导入

可以直接导入到方法的级别,方法必须是静态的
格式:import static 包名….类名.方法名;

package pers.terry.demo.jdk.jdk5.importStatic;

public class ImportStatic01 {
    public static String staticMethod(String say) {
        return "say:" + say;
    }

}
package pers.terry.demo.jdk.jdk5.importStatic;

import static pers.terry.demo.jdk.jdk5.importStatic.ImportStatic01.staticMethod;

public class ImportStatic02 {
    public static void main(String[] args) {
        System.out.println(staticMethod("terry"));
    }
}

可变参数(Varargs)

定义方法的时候不知道该定义多少个参数
格式: 修饰符 返回值类型 方法名(数据类型… 变量名){ }
注意: 这里的变量其实是一个数组,如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个

package pers.terry.demo.jdk.jdk5.varargs;

public class VarargsDemo {
    public static int sum(int... a) {
        System.out.println("a:"+a); //a是一个数组
        int s = 0;
        for (int x : a) {
            s += x;
        }
        return s;
    }

    public static void main(String[] args) { // 2个数据求和
        int a = 10;
        int b = 20;
        int c = 30;
        int d = 30;
        int result = sum(a, b);
        System.out.println("result:" + result);
        result = sum(a, b, c);
        System.out.println("result:" + result);
        result = sum(a, b, c, d);
        System.out.println("result:" + result);
        result = sum(a, b, c, d, 40);
        System.out.println("result:" + result);
        result = sum(a, b, c, d, 40, 50);
        System.out.println("result:" + result);
    }
}

参考:https://blog.csdn.net/gafeng123456/article/details/50764876

内省(Introspector)

主要用于操作JavaBean中的属性,通过getXxx/setXxx。一般的做法是通过类Introspector来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法。

Introspector.getBeanInfo()方法,得到的BeanInfo对象,BeanInfo的getPropertyDescriptors(),获得属性的描述PropertyDescriptor数组。PropertyDescriptor类表示JavaBean类通过存储器导出一个属性。主要方法:
  1. getPropertyType(),获得属性的Class对象;
  2. getReadMethod(),获得用于读取属性值的方法;getWriteMethod(),获得用于写入属性值的方法;
  3. hashCode(),获取对象的哈希值;
  4. setReadMethod(Method readMethod),设置用于读取属性值的方法;
  5. setWriteMethod(Method writeMethod),设置用于写入属性值的方法。
  6 getName, 获取属性名

package pers.terry.demo.jdk.jdk5.introspector;

public class User {
    private String name;
    private String address;

    public User() {
    }

    public User(String name, String address) {
        this.name = name;
        this.address = address;
    }

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    private String say(String words) {
        return "say:" + words;
    }
}


package pers.terry.demo.jdk.jdk5.introspector;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.Arrays;

public class IntrospectorDemo {
    public static void main(String[] args) throws Exception {
        final User user = new User();
        user.setName("nana");
        user.setAddress("hangzhou");

        //如果不想把父类的属性也列出来的话,那getBeanInfo的第二个参数填写父类的信息
        BeanInfo beanInfo = Introspector.getBeanInfo(user.getClass(), Object.class);
        PropertyDescriptor[] descriptor = beanInfo.getPropertyDescriptors();
        Arrays.stream(descriptor).forEach(x -> {
            try {
                System.out.println(x.getName() + " before: " + x.getReadMethod().invoke(user));
                x.getWriteMethod().invoke(user, "suzhou");
                System.out.println(x.getName() + " after: " + x.getReadMethod().invoke(user));
            } catch (ReflectiveOperationException e) {
                e.getLocalizedMessage();
            }
        });
    }
}

结果如下:
address before: hangzhou
address after: suzhou
name before: nana
name after: suzhou

参考:https://www.jianshu.com/p/086ba5cd3704

补充:
通过反射可以获得所有属性、构造方法的信息,和执行所有方法(包括private)。

package pers.terry.demo.jdk.jdk5.introspector;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

public class ReflexDemo {
    public static void testField(Class<?> clazz) {
//getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
//getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
//      Field[] fields = clazz.getFields();
        Field[] fields = clazz.getDeclaredFields();
        if (fields != null) {
            for (Field field : fields) {
                System.out.println(field.getModifiers() + " " + field.getType() + " " + field.getName());
            }
        }
    }

    public static void testConstructor(Class<?> clazz) {
//		Constructor<?>[] constructors = clazz.getConstructors();
        Constructor<?>[] constructors = clazz.getDeclaredConstructors();
        if (constructors != null) {
            for (Constructor<?> constructor : constructors) {
                System.out.println(constructor.getName() + "**" + constructor.getParameterTypes());
            }
        }
    }

    public static void testMethod(Class<?> clazz) {
//		Method[] methods = clazz.getMethods();
        Method[] methods = clazz.getDeclaredMethods();
        if (methods != null) {
            for (Method method : methods) {
                String methodName = method.getName();
                Class<?>[] paramTypes = method.getParameterTypes();
                System.out.println("methodName=" + methodName + "**params=" + Arrays.toString(paramTypes));

                if ("say".equals(methodName)) {    //say 方法是 private类型的
                    try {
                        method.setAccessible(true);    //暴力破解
                        Object result = method.invoke(clazz.getDeclaredConstructor().newInstance(), new Object[]{"haha"});
                        System.out.println(methodName + " invoke result=" + result);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        testField(User.class);
        testConstructor(User.class);
        testMethod(User.class);
    }
}

输出:
2 class java.lang.String name
2 class java.lang.String address
pers.terry.demo.jdk.jdk5.introspector.User**[Ljava.lang.Class;@6e2c634b
pers.terry.demo.jdk.jdk5.introspector.User**[Ljava.lang.Class;@37a71e93
methodName=getName** params=[]
methodName=setName** params=[class java.lang.String]
methodName=getAddress** params=[]
methodName=say** params=[class java.lang.String]
say invoke result=say:haha
methodName=setAddress**params=[class java.lang.String]

参考:https://blog.csdn.net/top_code/article/details/40784093

泛型(Generic)

泛型的好处:
1)将运行时期异常提前到了编译时期
2)优化了设计,解决了黄色警告线问题
3)避免了强制类型转换
4)提高了程序的安全性!
注意:类型参数只能代表引用型类型,不能是原始类型(像int,double,char的等)。

  1. 将泛型定义在类上:解决了向下类型转换出现的问题:ClassCastException
package pers.terry.demo.jdk.jdk5.generic;

public class ObjectTool<T> {
    private T obj;

    public T getObj() {
        return obj;
    }

    public void setObj(T obj) {
        this.obj = obj;
    }

    public static void main(String[] args) {
        //创建ObjectTool对象
        ObjectTool<String> ot = new ObjectTool<>() ;

        //赋值
        ot.setObj("高圆圆");
        String s = ot.getObj() ;
        System.out.println("ot:"+s);


        ObjectTool<Integer> ot2 = new ObjectTool<>() ;
        ot2.setObj(Integer.valueOf(12));
        System.out.println("ot2:"+ot2.getObj());
    }
}
  1. 将泛型定义在方法上
package pers.terry.demo.jdk.jdk5.generic;

import pers.terry.demo.jdk.jdk5.introspector.User;

public class ObjectTool2 {
    //泛型是可以在方法上定义的
    public <T> T show(T t) {
        System.out.println(t);
        return t;
    }

    public static void main(String[] args) {
        //创建ObjectTool类的对象
        ObjectTool2 ot = new ObjectTool2();
        ot.show("hello");
        ot.show(true);
        ot.show(100);
        ot.show(new User());
    }
}

  1. 将泛型定义在接口上
//将泛型定义在接口上
package pers.terry.demo.jdk.jdk5.generic;

public interface Inter<T> {
    //接口中变量是常量: public static final  int num ;
    public abstract void show(T t) ; //抽象方法
}
package pers.terry.demo.jdk.jdk5.generic;

//第一种情况:指定接口泛型
public class InterImpl implements Inter<String> {
    public static void main(String[] args) {
        Inter<String> i = new InterImpl();
        i.show("i");
    }

    @Override
    public void show(String t) {
        System.out.println("show:" + t);
    }
}

package pers.terry.demo.jdk.jdk5.generic;

//第一种情况:不指定接口泛型
public class InterImpl2<T> implements Inter<T> {
    public static void main(String[] args) {
        Inter<String> i = new InterImpl2();
        i.show("String");
        Inter<Integer> i2 = new InterImpl2();
        i2.show(2);
    }

    @Override
    public void show(T t) {
        System.out.println("show:" + t);
    }
}
  1. 泛型高级(通配符)
    <?>:代表任意类型Object类型,或者任意的Java类
    <? super E>:向上限定,E及其他的父类
    <? extends E>:向下限定,E的子类或者E这个类型
class Animal{	
}
class Cat extends Animal {	
} 
class Dog extends Animal{	
}
 
public static void main(String[] args) {		
		//创建集合对象,泛型如果明确的情况下,前后必须保持一致
		Collection<Object> c1 = new ArrayList<Object>() ;
//		Collection<Object> c2 = new ArrayList<Cat>() ;//错误
//		Collection<Object> c3 = new ArrayList<Animal>() ;//错误		
		
		//<?>  :代表任意类型Object类型,或者任意的Java类 
		Collection<?> c4 = new ArrayList<Object>() ;
		Collection<?> c5 = new ArrayList<Animal>() ;
		Collection<?> c6 = new ArrayList<Dog>() ;
		Collection<?> c7= new ArrayList<Cat>() ;
		
//		<? extends E>:向下限定,E的子类或者E这个类型
		Collection<? extends Object> c8 = new ArrayList<Object>() ;
		Collection<? extends Object> c9 = new ArrayList<Animal>() ;
		Collection<? extends Object> c10 = new ArrayList<Cat>() ;
//		Collection<? extends Aninal> c11 = new ArrayList<Object>() ;//错误
		
//		<? super E>:向上限定,E及其他的父类
//		Collection<? super Animal> c12 = new ArrayList<Cat>() ;//错误
		Collection<? super Animal> c13 = new ArrayList<Animal>() ;
		Collection<? super Animal> c14 = new ArrayList<Object>() ;		
	}

参考:https://blog.csdn.net/xing_ran_ran/article/details/80426642

For-Each循环

高级ForEach()是一种高级技术,它必须有遍历的目标,该目标要么是Arrays数组,要么是集合Collection单列集合,格式:
for(类型 变量:集合or数组){
      sysop();//输出语句
}

//遍历集合
List<String> list =new ArrayList<String>();
list.add("abc1");
list.add("abc2");
list.add("abc3");
for(String s : list){		
	System.out.println(s);			
}

//遍历map
Map<Integer,String> map=new HashMap<Integer,String >();
map.put(3,"zhagsan");
map.put(1,"wangyi");
map.put(7,"wagnwu");
map.put(4,"zhagsansan");
//直接对mapforEach
for(Map.Entry<Integer,String> me:map.entrySet()){
    Integer key=me.getKey();
    String value=me.getValue();
    System.out.println(key+":"+value);
}
//对key forEach,再取value
for(Integer key:map.keySet()){
    String value=map.get(key);
    System.out.println(key+":"+value);
}

参考:https://blog.csdn.net/zhanshixiang/article/details/82751759

注解

  1. 基本内置注释(JDK5.0自带的)
    1) Override 注释能实现编译时检查,你可以为你的方法添加该注释,以声明该方法是用于覆盖父类中的方法。如果该方法不是覆盖父类的方法,将会在编译时报错。例如我们为某类重写toString() 方法却写成了tostring() ,并且我们为该方法添加了@Override 注释,那么编译是无法通过的。
    2)Deprecated 的作用是对不应该在使用的方法添加注释,当编程人员使用这些方法时,将会在编译时显示提示信息,它与javadoc 里的 @deprecated 标记有相同的功能。
    3)SuppressWarnings 与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数值都是已经定义好了的,我们选择性的使用就好了,参数如下:
  • unused 没有被访问过的元素,去除警告。
  • deprecation 使用了过时的类或方法时的警告
  • unchecked 执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型
  • fallthrough 当 Switch 程序块直接通往下一种情况而没有 Break 时的警告
  • path 在类路径、源文件路径等中有不存在的路径时的警告
  • serial 当在可序列化的类上缺少 serialVersionUID 定义时的警告
  • finally 任何 finally 子句不能正常完成时的警告
  • all 关于以上所有情况的警告
  1. 自定义注释类型
@Target({ElementType.METHOD,ElementType.CONSTRUCTOR})
public @interface Greeting {
    public enum FontColor {RED, GREEN, BLUE}
    String title();
    String content();
    FontColor fontColor() default FontColor.RED;
}

@Greeting(title = "健康", content = "你最近身体好吗", fontColor = Greeting.FontColor.BLUE)
public static void sayHello(String name) {
}

参考:https://blog.csdn.net/xiaomageit/article/details/48695595

协变返回类型

子类overRide父类方法时,实际返回类型可以是要求的返回类型的一个子类型

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值