您的位置:首页 > 职场人生

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

2014-12-29 23:59 405 查看
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语句可以导入一个类或某个包中的所有类

//importstatic静态导入JDK5以后才有。语句导入一个类中的某个静态方法或所有静态方法

//无名包和有包名中的类在一起,没有package,则为无名包。

//一个类中只有一个public类,且源文件必须和类名一样,如果都没有public,则源文件名随意。

//当导入同一个类名时,

//使用无名包必须在同一个目录下。

//com.solaire.enhance.Week有包名为主,则是和com.solaire.enhance.*,则是无包名为主。同时

//有包名,则要加全称路径。

public
class
StaticImport{


public
static
void
main(String[]args){

//TODOAuto-generatedmethodstub

int
x;

System.out.println(max(
3
,
6
));

}


}


,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){

//TODOAuto-generatedmethodstub

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){

//TODOAuto-generatedmethodstub

Integeriboj=
3
;
//自动装箱

int
i=iboj+
1
;
//自动拆箱

System.out.println(i);


Integeri1=
13
;

Integeri2=
13
;
//-128~127,因为那么小的数,会经常使用,所以会会缓存,

System.out.println(i1==i2);


Integeri3=
137
;

Integeri4=
137
;
//数字大,就不会缓存,每个有自己的对象

System.out.println(i3==i4);

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

//简单才交模式,复杂就不是模式了。


Integeri5=Integer.valueOf(
12
);

Integeri6=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
TrafficLampnextLamp(){

return
GREEN;

}

},

GREEN(
45
){

public
TrafficLampnextLamp(){

return
YELLOW;

}

},

YELLOW(
5
){

public
TrafficLampnextLamp(){

return
RED;

}

};


public
abstract
TrafficLampnextLamp();

private
int
time;

private
TrafficLamp(
int
time){

this
.time=time;

}

}


//自己实现枚举类

public
class
Week{


private
Week(){

//TODOAuto-generatedconstructorstub

}

public
static
final
WeekMON=
new
Week();

public
static
final
WeekTUE=
new
Week();

public
static
final
WeekWED=
new
Week();

public
static
final
WeekTHU=
new
Week();

public
static
final
WeekFRI=
new
Week();

public
static
final
WeekSAT=
new
Week();

public
static
final
WeekSUN=
new
Week();


public
WeeknextDay(){

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
StringtoString(){

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(),例如,newDate().getClass()
Class.forName("类名"),例如,Class.forName("java.util.Date");
第一种和其他两种有不同的地方,当用它创建Class对象的引用时,不会自动的初始化该class对象,为了使用类而做的准备工作实际包含了3个步骤:

1,加载:这是有类加载器执行的。该步骤将查找字节码,然后创建一个Class对象。
2,链接:在链接阶段将验证类中的字节码,为静态域分配存贮空间,并且如果有需要的话,将解析这个类创建的对其他类的引用。
3,初始化:如果该类具有超类,对其初始化,执行静态初始化和静态初始化块
初始化被延迟到了对静态方法(构造器隐式的静态的)或者非静态域进行首次引用时。
class主要方法:
Field[]getFields()public成员FieldgetField(Stringname)
Field[]getDeclaredFields()全部成员FieldgetDeclaredField(Stringname)
ConstructorMethod类似

getDeclareingClass()外部类
getDecEncloseingClass()匿名外部类也可以
getClassLoader()获取加载类
getResourceAsInputStream()获取资源

reflect中的主要类:ConstructorFieldMethodModifier,分别描述了类的构造器,域,和方法,标示符。
ClassgetDeclaringClass()描述内部定义的类
Class[]getExceptionTypes()(constructor和Methods)描述方法抛出的异常
intgetModifiers()返回一个用于描述修饰符的整形值
StringgetName()用于返回项目名字
Class[]getParameterTypes()(constructor和methods)返回参数形参的类型数组Class对象
ClassgetReturnType()(methods)返回类型Class对象

staticStringtoString(intmodifiers)返回修饰字符串
staticbooleanisAbstruct(intmodifiers)
isFinal()isInterface()isPrivate()isNative()isProtect()isPublic()isStatic()isStrict()isSynchronized()isVolatile()

AccessibleObject安全管理:上面都继承该类,暴力反射
voidsetAccessible(booleanflag)为类设置可访问标志
booleanisAccessible返回对象的可访问标志
StaticvoidsetAccessible(AccessbleObject[]arrgy,booleanflag)

反射创建数组:
Array类允许动态的创建数组,例如将这个特性应用到Array中的copyOf方法实现,应该记得这个方法可以用于扩展已经填满的数组。
Parent[]a=newParent[100];
a=Arrays.copyOf(a,2*a.length);

如何写这样一个方法?
publicstaticObject[]badCopyOf(Object[]a,intlength)
{
Object[]array=newOjbect[new.length);
System.arraycopy(a,0,newArray,0,Math.min(a.length,newlength);
returnnewArray;//运行时出错
}
可以利用反射,Objectnewarray=Array.newInstance(componentType,newleng);

publicstaticObject[]badCopyOf(Object[]a,intlength)
{
Classcl=a.getClass();
if(!cl.isArray())returnnull;
Classcomponenttype=cl.getComponentType();
intnewlength=Array.getLength(a);
Objectnewarry=Array.newInstance(componentType,newleng);
System.arraycopy(a,0,newArray,0,Math.min(a.length,newlength);
returnnewarray;
}
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(ReflectPointpt1,StringpropertyName,

Objectobj)
throws
IntrospectionException,IllegalAccessException,

InvocationTargetException{


BeanInfoins=Introspector.getBeanInfo(pt1.getClass());

PropertyDescriptor[]props=ins.getPropertyDescriptors();


for
(PropertyDescriptorpd:props){


if
(pd.getName().equals(propertyName)){

Methodmethod=pd.getWriteMethod();

method.invoke(pt1,obj);


}

}

}

//

//直接new一个PropertyDescriptor对象的方式来让大家了解JavaBeanAPI的价值,

//先用一段代码读取JavaBean的属性,然后再用一段代码设置JavaBean的属性。

public
static
void
setProperties(Objectpt1,StringpropertyName,

Objectobj)
throws
IntrospectionException,IllegalAccessException,

InvocationTargetException{


PropertyDescriptorpd=
new
PropertyDescriptor(propertyName,pt1.getClass());

MethodmethodsetX=pd.getWriteMethod();

methodsetX.invoke(pt1,obj);


}

public
static
ObjectgetProperties(Objectpt1,StringpropertyName)

throws
IntrospectionException,IllegalAccessException,

InvocationTargetException{


PropertyDescriptorpd=
new
PropertyDescriptor(propertyName,pt1.getClass());

MethodmethodgetX=pd.getReadMethod();

ObjectretVal=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{

//TODOAuto-generatedmethodstub

ReflectPointpt1=
new
ReflectPoint(
1
,
3
);


BeanUtils.getProperty(pt1,
"x"
);
//returnString类型,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());


}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: