美文网首页
Java基础增强(jdk1.5的新特性)

Java基础增强(jdk1.5的新特性)

作者: 被时光移动的城 | 来源:发表于2018-03-03 10:40 被阅读7次

    本篇文章是在观看学习网络视频《黑马程序员张孝祥javase基础加强》时整理的,作为学习笔记记录下来,如有意见或建议欢迎指出。如转载,请注明出处。谢谢!

    1)静态导入

    2)可变参数

    A 只能出现在可变参数列表最后;
    B ...位于变量类型和变量名之间,前后有无空格都可以;
    C 调用可变参数和方法时,编译器为该可变参数隐含创建一个数组,再方法体中以数组的形式访问可变参数

    3)增强for循环

    A 语法

    for(type变量名:集合变量名){...}

    B 注意事项
    迭代变量必须再()中定义
    集合变量可以是数组或实现了Iterable接口的集合类
    C 实例

       public int add(int x,int... args){
            int sum = x;
            //增强for循环
            for(int arg:args){
                sum += arg;
            }
            return sum;
        }
    

    4)基本数据类型的自动拆箱与装箱

    一个字节内,-128-127 ,享元设计模式flyweight(如果很多很小的对象,他们有很多相同的东西,就可以把他们变成一个对象,不同的东西变成外部属性,作为方法的参数传入。外部属性称为外部状态,内部属性成为内部状态)

    Interger x = 11;
    Interger y = 11;
    System.out.println(x==y);//true
    Interger a = 150;
    Interger b = 150;
    System.out.println(a==b);//false
    

    5)枚举

    枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。
    枚举元素必须位于枚举体中的最开始的部分,枚举元素列表的后要有分号与其他成员分隔。把枚举中的成员方法或变量等放在枚举元素的前面,编译器报错。

    A 枚举中常用的方法

    枚举api.png
      int length = Enumtest.values().length;//集合长度
    

    B 实现带有构造方法的枚举
    构造方法必须是private;

    Enumtest enumtest = Enumtest.RED;
    
    public enum  Enumtest {
        RED,//无参
        GREEN(),//无参
        YELLOW(1);//有参,参数随意填写
        private Enumtest(){
            Log.e("TAG","无参构造方法");
        };
        private Enumtest(int i){
            Log.e("TAG","有参构造方法");
        };
    }
    
    运行结果图.png
    看可以发现,枚举在实例话对象的时候,会把内部所有的对象都实例化一遍。默认调用无参构造,若想有参的构造方法,则在成员()内加入参数;
    枚举元素 GREEN,GREEN()一样,都是调用默认的构造方法。
    C 带有抽象方法的枚举
    Enumtest enumtest = Enumtest.RED;
    Log.e("TAG",""+ enumtest.nextLight());
    
    public enum  Enumtest {
        RED {
            @Override
            public Enumtest nextLight() {
                return GREEN;
            }
        },
        GREEN() {
            @Override
            public Enumtest nextLight() {
                return YELLOW;
            }
        },
        YELLOW(1) {
            @Override
            public Enumtest nextLight() {
                return RED;
            }
        };
        private Enumtest(){
            Log.e("TAG","无参构造方法");
        };
        private Enumtest(int time){
            this.tiem = time;
            Log.e("TAG","有参构造方法");
        };
        private int tiem;
        //抽象
        public abstract Enumtest nextLight();
    
    }
    

    运行结果:


    带抽象方法的枚举.png

    D 枚举只有一个成员时,就可以作为一种单例的实现方式;

    6)反射(jdk 1.2)

    A 得到各个字节码对应的实例对象(Class类型)

    public static void main(String[] args) throws ClassNotFoundException {
            String str1 = "abd";
            Class cls1 = str1.getClass();
            Class cls2 = String.class;
            Class cls3 = Class.forName("java.lang.String");
            System.out.println(cls1==cls1);
            System.out.println(cls1==cls3);
        }
    

    运行结果:

    运行结果.png
    从运行结果可以看出,三个引用变量指向同一份字节码,虚拟机只会一份字节码。
    Class.forName()的作用?
    作用是返回字节码,返回的方式有两种,一种情况是这份字节码已经被java虚拟机被加载过(缓存起来),则直接返回;另一种情况是java虚拟机没有加载过,则用类加载器去加载,把加载过的字节码缓存到虚拟机中,以后要得到这份字节码就不需要再次加载了。
    B 九个预定义Class实例对象
    api图.png
    int.class == Interger.TYPE;//true
    

    C 数组类型的Class对象

    Class.isArray();
    

    总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如 int[] , void...
    D 什么是反射
    反射就是把Java类中的各个成分映射成相应的java类。
    E 构造方法的反射应用
    Constructor类代表某个类中的一个构造方法
    得到所有的构造方法getConstructors():

    //例子,两种结果相同
     Constructor[] Constructor1 = String.class.getConstructors();
     Constructor[] Constructor2 = Class.forName("java.lang.String").getConstructors();
    

    得到某个构造方法
    获得方法时要用类型

    //例子
       Constructor<?> constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
    

    创建实例对象
    调用获得的方法时要用到上面相同类型的实例对象

    通常方式:String str = new String("abc");
    
    反射方式:String str =  Class.forName("java.lang.String").getConstructor().newInstance(new StringBuffer("abc"));
    

    Class.newInstancee()方法:

       //例子:
       //通过反射实现  new String(new StringBuffer("abc));
            Constructor<?> constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
            String abc = (String) constructor.newInstance(new StringBuffer("abc"));
            System.out.println(abc);
    

    运行结果:


    Constructor事例.png

    F 成员变量的反射(Field类)
    Field类代表某个类中的一个成员变量

    //定义一个类
    class ReflectPoint{
            private int x;
            public int y;
    
            public ReflectPoint(int x, int y) {
                this.x = x;
                this.y = y;
            }
        }
    
    //反射获取
            ReflectPoint mReflectPoint = new ReflectPoint(3,5);//初始化
            Field fieldy = mReflectPoint.getClass().getField("y");//获取fieldy
            //filed值是多少?是5,错!field不是对象身上的变量,而是类上,要用它去取某个对象对应的值
            //很多对象身上都有fieldy,那么到哪个对象身上去取呢,那就传入哪个对象
            System.out.println(fieldy.get(mReflectPoint));
            //获取不可见(private等)变量
            Field fieldx = mReflectPoint.getClass().getDeclaredField("x");
            //暴力反射,不然fieldx.get(mReflectPoint)会报 java.lang.IllegalAccessException异常
            fieldx.setAccessible(true);
            System.out.println(fieldx.get(mReflectPoint));
    

    运行结果:


    运行结果.png

    获取字段类型obj.getClass().getField().getType();

    因为字节码只有一份,所以同一份字节码的对比应用”==“而不是equals
    练习:将任意一个对象中的所有String类型真的成员变量对应的字符串内容中的”b“改成”--A--“

    //类
    public class RPoint {
        private int x;
        public int y;
        public String str1;
        public String str2;
        public String str3;
    
        public RPoint(int x, int y, String str1, String str2, String str3) {
            this.x = x;
            this.y = y;
            this.str1 = str1;
            this.str2 = str2;
            this.str3 = str3;
        }
    
        @Override
        public String toString() {
            return "RPoint{" +
                    "x=" + x +
                    ", y=" + y +
                    ", str1='" + str1 + '\'' +
                    ", str2='" + str2 + '\'' +
                    ", str3='" + str3 + '\'' +
                    '}';
        }
    }
    //-----------------------------------------------------------------
    //替换
     public static void main(String[] args) throws Exception {
            RPoint rPoint = new RPoint(3, 5,"abcdb","adkfl","有b哈哈b嗝");//实例化对象
            Field[] fields = rPoint.getClass().getFields();
            for(Field field:fields){
                //字节码只有一份,所以用==会比equals更好一些
                if(field.getType()==String.class){
                    String oldS = (String) field.get(rPoint);//field.get();
                    String newS = oldS.replace("b","--A--");
                    field.set(rPoint,newS);//field.set();
                }
            }
            System.out.println(rPoint);
        }
    

    运行结果:


    练习运算结果.png

    G 成员方法反射(Method类
    Method类代表某个类中的一个成员方法
    得到类中的一个方法:

    Method methodCharAt = String.class.getMethod("charAt",int.class);
    调用方法
    通常方式:str.charAt(1);
    反射方式:charAt.invoke(str1,1);
    如果传递给Method对象的invoke()方法的一个参数为null,说明Method对象对应的是一个静态方法

    实例:

            String str1 = "abc";
            //str1.charAt(1)
            Method methodCharAt = String.class.getMethod("charAt",int.class);//方法名,参数(可变参数)
            //methodCharAt.invoke(str1,1);(哪一个对象,传参)
            System.out.println(methodCharAt.invoke(str1,1));
    

    invoke(Object obj, Object... args)
    对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。

    运行结果:


    实例运行结果.png

    H 对接收数组参数的成员方法进行反射
    实例:用反射的方式执行某个类中的main方法

    《 黑马程序员张孝祥JavaSE基础加强》视频中图.png
    args[0]就是要启动的class的name
    《黑马程序员张孝祥JavaSE基础加强》视频中图.png

    I
    J
    K
    L
    M
    N
    O

    7)ArrayList和HashSet的比较及Hashcode分析

    8)注解

    9)泛型

    10)java的动态代理

    相关文章

      网友评论

          本文标题:Java基础增强(jdk1.5的新特性)

          本文链接:https://www.haomeiwen.com/subject/uhlaxftx.html