黑马程序员__Java高新技术一

来源:互联网 发布:c语言入门经典书籍 编辑:程序博客网 时间:2024/05/24 02:10


---------- android培训、java培训、期待与您交流! ----------

 

享元模式(自动装箱拆箱)

Integer a = 137;

Integer b = 137;

Integer i = 95;

Integer j = 95;

// 这是一种设计模式:享元模式flyweight.

// 如果很多很小的对象,如果他们有相同的东西,那就把他变成一个对象。

// 把不同的东西,变成外部的属性,作为方法的参数传入。

// 比如文件夹图标。

System.out.println(a == b);// false

System.out.println(i == j);// true//对象比较小,为了共用一个对象,在一个字节内,不需要另外开辟空间

枚举

//普通类模拟枚举实现原理代码

publicabstractclass WeekDay {

 

    private WeekDay() {

    }

 

    publicfinalstatic WeekDayMON =new WeekDay() {

 

       @Override

       public WeekDay nextDay() {

           returnSUN;

       }

    };

 

    publicfinalstatic WeekDaySUN =new WeekDay() {

       @Override

       public WeekDay nextDay() {

           returnMON;

       }

    };

    //采用抽象方法定义nextDay就将大量的if.else语句转移成了一个个独立的类

    publicabstract WeekDay nextDay();

}

 

 

//枚举的基本应用及带有构造方法的枚举

    publicstaticvoid main(String[] args) {

       WeekDay wd = WeekDay.SUN;

       System.out.println(wd);//可以直接输出,说明枚举类里面已经重写了toString();

       //对象方法

       System.out.println(wd.name());

       System.out.println(wd.ordinal());//排第几,从0开始。

       //静态方法

       System.out.println(WeekDay.valueOf("MON"));//字符串变成对象

       System.out.println(WeekDay.values().length);//把元素转成数组,再求长度

 

    }

    //枚举是一个类。

    publicenum WeekDay {

       SUN(1),MON(),TUE,WED,THU,FRI,SAT;

       //枚举的所有方法,必须位于所枚举的元素之后,并在元素后用分号隔开。

       //构造方法不能公共,因为不能给外部创建对象

       //另外,只要你用到枚举类,上面的枚举对象就会被初始化,构造方法就会被调用

       //如果想调用有参构造方法。可以在对象后面加上参数列表,如SUN(1)

       //所以对象后面也可以用空括号表示,如MON();

       WeekDay() {

           System.out.println("无参构造方法");

       }

 

       WeekDay(int day) {

           System.out.println("有参构造方法");

       }

    }

//带有抽象方法的枚举

// 枚举交通灯

    publicenum TrafficLamp {

       RED(30) {

           @Override

           public TrafficLamp nextLamp() {

              returnGREEN;

           }

       },

       GREEN(45) {

           @Override

           public TrafficLamp nextLamp() {

              returnYELLOW;

           }

       },

       YELLOW(5) {

           @Override

           public TrafficLamp nextLamp() {

              returnRED;

           }

       };

       //枚举是一个抽象类

       publicabstract TrafficLamp nextLamp();

 

        privateinttime;

 

       TrafficLamp(int time) {

           this.time = time;

       }

    }

// 枚举只有一个成员时,就是一种单例的实现方式。

 

 

 

反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

  Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

反射的基石-->Class

 

Java程序中,各个类都是""这一类事物,用"Class"这个类来描述众多的Java

 

Class实例对象,代表内存中的一段字节码。比如内存中加载了三个class文件,Class对象就是这些文件的字节码文件。

 

所以创建Class实例对象的三种方式如下:

    String str = "abc";

    Class cls1 = str.getClass();

    Class cls2 = String.class;

    Class cls3 = Class.forName("java.lang.String");//引号里指定类的全名

    // Class类中的静态方法,实际开发中都使用这个,因为参数列表可以传递字符串

    //如果String类没加载进内存,forName会自动加载并获得。

    System.out.println(cls1 == cls2);// true

    System.out.println(cls3 == cls2);// true

    //这三种方式,获得的字节码对象都是同一个对象

 

// 九个预定义Class实例对象,8个基本数据类型//(boolean,byte,char,short,int,long,float,double)+void

// 既,可以Classcls=void.class();

    System.out.println(cls1.isPrimitive());// false//是否是原始对象,既是否是预定义对象 // 包括数组也不是预定义对象

    System.out.println(int.class.isPrimitive());// true

    System.out.println(int.class == Integer.class);// false

System.out.println(int.class == Integer.TYPE);// true // TYPE表示Interger这个包装类所包装基本类型的字节码。

 

    System.out.println(int[].class.isArray());// true //是否是数组类型的Class实例对象。

 

 

Constructor

// 获得String类里面,构造方法的参数是StringBuffer类型的构造方法

Constructor cst = String.class.getConstructor(StringBuffer.class);

 

// 通过这个构造方法,实例化一个对象。newInstance返回类型是Object,所以需要强转。

String str = (String) cst.newInstance(new StringBuffer("abc"));

 

Field

        Person p = new Person("lisi", 15);

       Field fieldAge = p.getClass().getField("age");//只能访问公有属性

       Field fieldName = p.getClass().getDeclaredField("name");//都可以访问

       //因为是p.getClass()其实这个获得属性agePerson类的age,所以下面要获得p这个对象的年龄,必须指定对象。

       System.out.println(fieldAge.get(p));

       //虽然能知道有"name"这个属性了,但是还是不能直接获得,所以要设置可以访问         fieldName.setAccessible(true); (暴力反射)

System.out.println(fieldName.get(p));

 

 

 

 

 

//例题:将一个对象中所有String类型的成员变量所对应的字符串内容中的”b”改成”a”

import java.lang.reflect.Field;

class StringDemo {

    String s1 = "ball";

    String s2 = "basketball";

    String s3 = "itheima";

    intnum = 5;

 

    @Override

    public String toString() {

       returns1 +" + s2 + " + s3 +" + num;

    }

 

}

 

publicclass Test {

 

    publicstaticvoid main(String[] args)throws Exception {

      

       StringDemo sd = new StringDemo();

       ChangeObjectValue(sd);

       System.out.println(sd);

    }

 

    publicstatic Object ChangeObjectValue(Object obj)throws Exception {

       //思路:首先获得对象所在的类,然后获得类的所有属性

       Field[] fields = obj.getClass().getDeclaredFields();// fields是代表类的所有属性

 

       for (Field f : fields) {

           //判断属性的类型的字节码是不是String(既和String的字节码是不是同一份),所以用"=="号来判断

           //如果是,获得属性的值并修改。

           if (f.getType() == String.class) {

              String oldValue = (String) f.get(obj); //get方法 返回指定对象上此Field表示的字段的值

              String newValue = oldValue.replace('b','a');

              f.set(obj, newValue);

           }

       }

       return obj;

    }

}

 

 

 

---------- android培训、java培训、期待与您交流! ----------

原创粉丝点击