黑马程序员——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());

}

 

时间: 2024-08-02 06:57:58

黑马程序员——JAVA学习笔记十二(高新技术一)的相关文章

黑马程序员——JAVA学习笔记十四(高新技术三)

10 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供定的服务. 按照代理的创建时期,代理类可以分为两种. 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了. 动态代

黑马程序员——JAVA学习笔记十(IO)

1,    可以从其中读入一个字节序列的对象成为输入流,可以向其中写入一个字节序列的对象就做输出流.这些字节序列的来源地可以是文件,也可以是网络连接或者内存块.抽象类InputStream和OutputStream构成了I/O层次的基础.因为字节流不便于处理以Unicode存储的信息,所以有了Writer和Reader抽象类,这些从其中继承的类都是读入和写入基于2个字节的Unicode码元,而不是单个字节.   2,    InputStream 与OutputStream: abstract

黑马程序员——JAVA学习笔记五(异常)

1,     异常:是在运行时期发生的不正常情况. 在java中用类的形式对不正常情况进行了描述和封装对象.描述不正常的情况的类,就称为异常类. 以前正常流程代码和问题处理代码相结合,现在将正常流程代码和问题处理代码分离,提高阅读性. 其实异常就是java通过面向对象的思想将问题封装成了对象,用异常类对其进行描述. 不同的问题用不同的类进行具体的描述.比如角标越界.空指针异常等等. 问题很多,意味着描述的类也很多,将其共性进行向上抽取,形成了异常体系. 不正常情况分成了两大类: Throwabl

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

8,    注解 Annotation(注解)是JDK5.0及以后版本引入的. 注解是以 @注解名 的形式标识 注解不会影响程序语义,只作为标识 注解是新的类型(与接口很相似),它与类.接口.枚举是在同一个层次,它们都称作为java的一个类型(TYPE). 它可以声明在包.类.字段.方法.局部变量.方法参数等的前面,用来对这些元素进行说明,注释. 它的作用非常的多,例如:进行编译检查.生成说明文档.代码分析等 注释类型 是一种特殊的接口 用 @interface 声明如 [email prote

黑马程序员----java学习笔记之数组、二维数组,附相关面试题

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- 一:数组(掌握) (1)数组:存储同一种数据类型的多个元素的容器. (2)特点:每一个元素都有编号,从0开始,最大编号是长度-1. 编号的专业叫法:索引 (3)定义格式 A:数据类型[] 数组名; B:数据类型 数组名[]; 推荐是用A方

黑马程序员——JAVA学习笔记二(语法基础)

1,     Java程序都是以类的形式存在的,所以需要告诉虚拟机需要加载类的位置,那么可以设置classpath变量.classpath变量如果有;,则表示还会在当前目录查找,没有;则不会在当前目录查找. 当然如果没有classpath也会在当前目录查找. 2,    rd删除目录,加/S可以删整个目录,Windows从里向外删除. 3,    一个文件只有一个public类,文件名必须和类名相同,如果不是友好类,则不需要同名. 4,    JAVA一共有50个关键字 关键字是电脑语言里事先定

黑马程序员——JAVA学习笔记六(多线程)

1,    什么是多线程?一个程序可以执行多个任务,每一个任务称为一个线程,运行多个线程的程序称为多线程程序. 进程:正在进行中的程序(直译). 线程:进程中一个负责程序执行的控制单元(执行路径).   多线程的好处:解决了多部分代码同时运行的问题.多线程的弊端:线程太多,会导致效率的降低. 其实,多个应用程序同时执行都是CPU在做着快速的切换完成的.这个切换是随机的.CPU的切换是需要花费时间的,从而导致了效率的降低 2 ,    创建线程方式:  创建线程方式一:继承Thread类 1.定义

黑马程序员——JAVA学习笔记十一(文件操作File)

为了很方便的代表文件的概念,以及存储一些对于文件的基本操作,在java.io包中设计了一个专门的类——File类. 在File类中包含了大部分和文件操作的功能方法,该类的对象可以代表一个具体的文件或文件夹,所以以前曾有人建议将该类的类名修改成FilePath,因为该类也可以代表一个文件夹,更准确的说是可以代表一个文件路径. 1.创建文件 1)boolean java.io.File.createNewFile() throws IOException用来创建文件,如果文件存在,创建失败,返回fa

黑马程序员——JAVA学习笔记八(集合)

1,    JAVA最初版本只为最常用的数据结构提供了很少的一组类:Vector.Stack.Hashtable.BitSet与Enumeration接口,从JAVA1.2版本开始推出了一组功能完善的的数据结构. 集合类的由来:  对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定.  就使用集合容器进行存储. 集合特点: 1,用于存储对象的容器. 2,集合的长度是可变的. 3,集合中不可以存储基本数据类型值. 4,接口与实现相互分离. 集合框架是为表示和操作集合而规定的一种统一的标准