• 黑马程序员——JAVA学习笔记十二(高新技术一)


     1,    静态导入:
     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    package com.solaire.enhance;
    import static java.lang.Math.max; 
    //import   语句可以导入一个类或某个包中的所有类
    //import static  静态导入 JDK5以后才有。语句导入一个类中的某个静态方法或所有静态方法
    //无名包和有包名中的类在一起,没有package,则为无名包。
    //一个类中只有一个public类,且源文件必须和类名一样,如果都没有public,则源文件名随意。
    //当导入同一个类名时,
    //使用无名包必须在同一个目录下。
    //com.solaire.enhance.Week 有包名为主 ,则是和com.solaire.enhance.*,则是无包名为主。同时
    //有包名,则要加全称路径。
    public class StaticImport {
     
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int x;
            System.out.println(max(36));
        }
     
    }
    ,2,    可变参数与for循环增强
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public class VariedParameter {
     
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            add(1,2,3,4,5,6);
            System.out.print(add(1,2,3,4,5,6));
        }
         
    //      可变参数的特点:
    //      只能出现在参数列表的最后;这个要记住
    //      ...位于变量类型和变量名之间,前后有无空格都可以;
    //      调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。
        public static int add(int ... args) {
            int sum = 0;
           for(int i = 0; i < args.length; i++) {
                sum += args[i];
            }
    //         语法:
    //         for ( type 变量名:集合变量名 )  { … } 
    //         注意事项:
    //         迭代变量必须在( )中定义!
    //         集合变量可以是数组或实现了Iterable接口的集合类
           sum = 0;
            for(final int i: args){ //for高级特性
                sum += i;         //变量名:集合
            }
            return sum;
        }
     
    }
    3,    基本数据类型的自动拆箱与装箱
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    //对象包装器,Integer ,Long, Double, Float, Short, Byte,Chararter,Void, Boolean
    //(前6个派生于Number类)。是不可继承类,一旦构造了包装器,就不允许更改包装器里面的值。
    //装箱:XXX.valueOf() 拆箱:XXX.xxvalue(),自动装箱规范要求boolean,byte,char<= 127,
    //介于-128~127之间的short 和int被包装到固定的对象中。
    public class AutoBoxClass {
     
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Integer iboj = 3//自动装箱
            int i = iboj + 1//自动拆箱
            System.out.println(i);
             
            Integer i1 = 13;
            Integer i2 = 13;// -128 ~127,因为那么小的数,会经常使用,所以会会缓存,
            System.out.println(i1 == i2);
             
            Integer i3 = 137;
            Integer i4 = 137;// 数字大,就不会缓存,每个有自己的对象
            System.out.println(i3 == i4);
            //这是一种设计模式,享元模式flyweight
            //简单才交模式,复杂就不是模式了。
             
            Integer i5 = Integer.valueOf(12);
            Integer i6 = Integer.valueOf(12);// 
            System.out.println(i5 == i6);
        }
     
    }
    4,    枚举
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    //  枚举:枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,
    //  否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序
    //  中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。
    //  在比较两个枚举类是不用euqals,直接用==
    //  可以在枚举类型中添加构造器,方法和域。构造器只是在构造枚举常量的时候被调用。
    //  所有的枚举类型都是Enum类的子类,继承了这个类的很多方法。
    //  常用方法: class.values()
    //  Enum.valueOf(class , string)    class.valueof()  object.ordinl()
    //  枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后要有分号与其他成员分隔。
    //  把枚举中的成员方法或变量等放在枚举元素的前面,编译器报告错误。
        public enum TrafficLamp{
            RED(30){
                public TrafficLamp nextLamp(){
                    return GREEN;
                }
            }, 
            GREEN(45){
                public TrafficLamp nextLamp(){
                    return YELLOW;
                }
            }, 
            YELLOW(5){
                public TrafficLamp nextLamp(){
                    return RED;
                }
            };
             
            public abstract TrafficLamp nextLamp();
            private int time;
            private TrafficLamp(int time){
                this.time = time;
            }
        }
     
    //自己实现枚举类
    public class Week {
     
        private Week() {
            // TODO Auto-generated constructor stub
        }
        public static final Week  MON = new Week();
        public static final Week  TUE = new Week();
        public static final Week  WED = new Week();
        public static final Week  THU = new Week();
        public static final Week  FRI = new Week();
        public static final Week  SAT = new Week();
        public static final Week  SUN = new Week();
         
        public Week nextDay() {
            System.out.println("******************************");
            if  (this == SAT)
                return SUN;
            else if(this == SUN  )
                return MON;
            else if(this == MON  )
                return TUE;
            else if(this == TUE )
                return WED;
            else if(this ==WED  )
                return THU;
            else if(this == THU  )
                return FRI;
            else if(this == FRI  )
                return SAT;
            else 
                return null;
     
        }
        public String toString(){
            System.out.println("****************************");
            if  (this == SAT)
                return "SAT";
            else if(this == SUN  )
                return "SUM";
            else if(this == MON  )
                return "MON";
            else if(this == TUE )
                return "TUE";
            else if(this ==WED  )
                return "WED";
            else if(this == THU  )
                return "THU";
            else if(this == FRI  )
                return "FRI";
            else
                return null;
        }
    }
    5,    反射
    在程序运行期间,JAVA始终为所有对象维护一个被称为运行时的类型标示。保存这些信息的类称为Class,Class类代表Java类,它的各个实例对象又分别对应什么呢?
    对应各个类在内存中的字节码,例如,Person类的字节码,ArrayList类的字节码,等等。 一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码, 
    不同的类的字节码是不同的,所以它们在内存中的内容是不同的,这一个个的空间可分别用 一个个的对象来表示,这些对象显然具有相同的类型,这个类型是就是class类。
     
     
    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
     
     
    能够分析类能力的程序称为反射。反射机制可以用来:
    在运行中分析类的能力
    在运行中查看对象
    实现通用的数组操作代码
    利用Method对象,这个对象很像C++中的函数指针
     
    如何得到各个字节码对应的实例对象(3种)
    ( Class类型) 类名.class,例如,System.class
    对象.getClass(),例如,new Date().getClass()
     Class.forName("类名"),例如,Class.forName("java.util.Date");
    第一种和其他两种有不同的地方,当用它创建Class对象的引用时,不会自动的初始化该class对象,为了使用类而做的准备工作实际包含了3个步骤:
    1,加载:这是有类加载器执行的。该步骤将查找字节码,然后创建一个Class对象。
    2,链接:在链接阶段将验证类中的字节码,为静态域分配存贮空间,并且如果有需要的话,将解析这个类创建的对其他类的引用。
    3,初始化: 如果该类具有超类,对其初始化,执行静态初始化和静态初始化块
    初始化被延迟到了对静态方法(构造器隐式的静态的)或者非静态域进行首次引用时。
    class主要方法:
    Field[] getFields() public成员     Field getField(String name)
    Field[] getDeclaredFields()  全部成员     Field getDeclaredField(String name)
    Constructor  Method  类似
     
    getDeclareingClass()外部类
    getDecEncloseingClass() 匿名外部类也可以
    getClassLoader()获取加载类
    getResourceAsInputStream()获取资源
     
    reflect中的主要类:Constructor   Field   Method  Modifier,分别描述了类的构造器,域,和方法,标示符。
    Class getDeclaringClass() 描述内部定义的类
    Class[] get ExceptionTypes() (constructor 和 Methods)  描述方法抛出的异常
    int  getModifiers()  返回一个用于描述修饰符的整形值
    String getName()  用于返回项目名字
    Class[ ] getParameterTypes()(constructor 和methods)  返回参数形参的类型数组Class对象
    Class  getReturnType() (methods)  返回类型Class对象
     
    static  String toString(int modifiers)  返回修饰字符串
    static boolean isAbstruct(int modifiers)  
    isFinal() isInterface()  isPrivate()  isNative() isProtect() isPublic() isStatic() isStrict() isSynchronized()  isVolatile()
     
    AccessibleObject安全管理:上面都继承该类,暴力反射
    void  setAccessible(boolean flag)  为类设置可访问标志
    boolean isAccessible  返回对象的可访问标志
    Static void setAccessible(AccessbleObject [] arrgy , boolean flag) 
     
    反射创建数组:
    Array类允许动态的创建数组,例如将这个特性应用到Array中的copyOf方法实现,应该记得这个方法可以用于扩展已经填满的数组。
    Parent[] a = new Parent[100];
    a = Arrays.copyOf(a, 2*a.length);
     
    如何写这样一个方法?
    public   static Object[] badCopyOf(Object[] a , int length) 
    {
    Object [] array = new Ojbect[new.length);
    System.arraycopy(a, 0, newArray, 0, Math.min(a.length, newlength);
    return newArray; //运行时出错
    }
    可以利用反射, Object new array = Array.newInstance(componentType, newleng);
    public   static Object[] badCopyOf(Object[] a , int length) 
    {
    Class cl = a.getClass();
    if(!cl.isArray()) return null;
    Class componenttype = cl.getComponentType();
    int newlength = Array.getLength(a);
    Object newarry = Array.newInstance(componentType, newleng);
    System.arraycopy(a, 0, newArray, 0, Math.min(a.length, newlength);
    return newarray;
    }
    int [] a  = {1,2,3,4,5};
    a = (int[] ) goodCopy(a, 10);
    反射调用方法:
    invoke()(method)  返回值:如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型, 
    则首先适当地将其包装在对象中。但是,如果该值的类型为一组基本类型, 则数组元素不被包装在对象中;换句话说,将返回基本类型的数组。
    如果底层方法返回类型为 void,则该调用返回 null。
     
    因为invoke参数和返回类型必须是Object类型的,意味着必须要多次进行强制转换,这样做编译器错过了检查代码的机会。所以在必要的时候再用它。
    反射实现框架:
    框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类。
     
     
    6,    JavaBean内省
    JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性。
     
    作为一个黑盒子的模型,JavaBean有3个接口面,可以独立进行开发。
    1. JavaBean可以调用的方法。
    2. JavaBean提供的可读写的属性。
    3. JavaBean向外部发送的或从外部接收的事件。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    //  采用遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的x属性。
    //  在程序中把一个类当作JavaBean来看,就是调用IntroSpector.getBeanInfo方法, 
    //  得到的BeanInfo对象封装了把这个类当作JavaBean看的结果信息。
        public static void setProperties1(ReflectPoint pt1, String propertyName,
                Object obj) throws IntrospectionException, IllegalAccessException,
                InvocationTargetException {
             
            BeanInfo ins = Introspector.getBeanInfo(pt1.getClass());
            PropertyDescriptor [] props = ins.getPropertyDescriptors();
             
            for(PropertyDescriptor pd : props) {
                 
                if(pd.getName().equals(propertyName)) {
                    Method method = pd.getWriteMethod();
                    method.invoke(pt1, obj);
                     
                }
            }
        }
    //
    //  直接new一个PropertyDescriptor对象的方式来让大家了解JavaBean API的价值,
    //  先用一段代码读取JavaBean的属性,然后再用一段代码设置JavaBean的属性。
        public static void setProperties(Object pt1, String propertyName,
                Object obj) throws IntrospectionException, IllegalAccessException,
                InvocationTargetException {
             
            PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
            Method methodsetX = pd.getWriteMethod();
            methodsetX.invoke(pt1, obj);
             
        }
        public static Object getProperties(Object pt1, String propertyName)
                throws IntrospectionException, IllegalAccessException,
                InvocationTargetException {
             
            PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
            Method methodgetX = pd.getReadMethod();
            Object retVal = methodgetX.invoke(pt1);
            return retVal;
             
        }
    7,    beanutils工具包 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        ReflectPoint pt1 = new ReflectPoint(13);
         
        BeanUtils.getProperty(pt1,"x");//return  String类型 ,BeanUtils以字符串操作
        BeanUtils.setProperty(pt1, "x""9");
        System.out.println(pt1.getX()+"......"+BeanUtils.getProperty(pt1,"x").getClass().getName());
         
        BeanUtils.setProperty(pt1, "birthday.time",4000);//属性链一级级的向下
        System.out.println(BeanUtils.getProperty(pt1,"birthday")+"..........."+
                            BeanUtils.getProperty(pt1,"birthday").getClass().getName());
         
         
        PropertyUtils.setProperty(pt1, "x"8);  //返回原始类型,PropertyUtils以原始类型操作
        System.out.println(pt1.getX());
     
    }

     

  • 相关阅读:
    面试系统化学习和准备(一)——今日事必须今日毕
    20220324准备
    面试系统化学习和准备(二)——docker篇
    20220325目标
    任务调度系统
    二叉树最大路径和
    count(*)这么慢,我该怎么办?
    动态规划最长连续递增序列
    设置工作模式与环境(上):建立计算机
    Django 数据库配置(二)
  • 原文地址:https://www.cnblogs.com/solaire/p/4192690.html
Copyright © 2020-2023  润新知