java与C#的异同2.docx
《java与C#的异同2.docx》由会员分享,可在线阅读,更多相关《java与C#的异同2.docx(13页珍藏版)》请在冰豆网上搜索。
![java与C#的异同2.docx](https://file1.bdocx.com/fileroot1/2023-2/23/dfdb74d5-732b-4718-900c-078fa6c4f322/dfdb74d5-732b-4718-900c-078fa6c4f3221.gif)
java与C#的异同2
四、枚举:
枚举的是在Java1.5SE中开始支持的,以下为Java枚举的基本概念和应用技巧:
1. 所有的enum对象均是由class对象作为底层支持的,该对象继承自JDK中的Enum,但是该底层类确实final类,既不能再被其他的类继承。
2. 枚举的出现完全替代了原有的"publicstaticfinal"常量表示法,枚举以一种更加合理、优雅和安全的方式替换了原有的方案。
其最基本的声明方式如下:
1publicenumColor{
2RED,BLUE,BLACK,YELLOW
3}
3. Enum中构造函数的原型为protectedEnum(Stringname,intordinal),自定义的枚举对象会将自身的名字以字符串的形式,同时将自己在整个常量从声明的顺序作为超类构造函数的两个参数传给超类并由超类完成必要的初始化,如:
RED枚举常量将调用super("RED",0)。
4. 枚举中可以定义构造函数、域方法和域字段,但是枚举中的构造器必须是私有(private)的,如果自定义枚举中有了自定义的构造函数,那么每个枚举常量在声明时必须按照自定义构造函数的规则传入参数。
枚举对象的构造函数只是在枚举常量对象声明的时刻才调用一次,之后再也不能像普通对象那样通过new的方法创建,见如下代码:
1publicenumSize{
2SMALL(0.8),
3MEDIUM(1.0),
4LARGE(1.2);
5doublepricingFactor;
6privateSize(doublep){
7pricingFactor=p;
8}
9}
注:
枚举常量列表必须写在最前面声明,否则编译器报错。
5. 可以给自定义枚举添加域方法,见如下代码:
1publicenumSize{
2SMALL(0.8),
3MEDIUM(1.0),
4LARGE(1.2);
5privatedoublepricingFactor;
6Size(doublep){
7pricingFactor=p;
8}
9publicdoublegetPricingFactor(){
10returnpricingFactor;
11}
12}
6. 枚举中常用域方法:
1publicenumSize{
2SMALL,
3MEDIUM,
4LARGE;
5}
6publicstaticvoidmain(String[]args){
7//两种获得枚举类型的方法
8Sizes1=Size.SMALL;
9//valueOf的函数原型为>TvalueOf(ClassenumType,Stringname)
10Sizes2=Enum.valueOf(Size.class,"SMALL");
11//Size(自定义枚举)的valueOf方法是Java编译器在生成字节码的时候自动插入的。
12Sizes3=Size.valueOf("MEDIUM");//1
13
14//结果同上,枚举重载了equals方法
15System.out.println("Size.MEDIUM.equals(Enum.valueOf(Size.class,\"MEDIUM\")):
"+
16Size.MEDIUM.equals(Enum.valueOf(Size.class,"MEDIUM")));
17
18//遍历枚举类型中所有的成员,这里应用的Size.values方法和Size.valueOf方法
19//一样均是编译器在生成字节码的时候自动插入的。
20for(Sizes:
Size.values()){//2
21//ordinal()和name()方法均为Enum提供的方法,返回枚举常量在声明时的构
22//造函数中自动调用超类构造函数时传入的自身字符串名和在声明列表中的序号
23System.out.println(s.ordinal()+""+s.name()+""+s.toString());
24}
25//compareTo方法缺省比较的是枚举常量的ordinal()的返回值。
26if(pareTo(s3)<0)
27System.out.println("Size.SMALLislessthanSize.MEDIUM");
28}
7. 在枚举中可以声明基于特定常量的类主体,见如下代码:
1publicenumSize{
2//Small、ExtraLarge和ExtraExtraLarge均使用自定义的getPricingFactor
3//方法覆盖Size提供的缺省getPricingFactor方法。
4Small{
5@Override
6publicdoublegetPricingFactor(){
7return0.8;
8}
9},
10//Medium和Large将使用Size内部缺省实现的getPricingFactor方法。
11Medium,
12Large,
13ExtraLarge{
14@Override
15publicdoublegetPricingFactor(){
16return1.2;
17}
18},
19ExtraExtraLarge{
20@Override
21publicdoublegetPricingFactor(){
22return1.2;
23}
24};
25publicdoublegetPricingFactor(){
26return1.0;
27}
28}
29publicstaticvoidmain(Stringargs[]){
30for(Sizes:
Size.values()){
31doubled=s.getPricingFactor();
32System.out.println(s+"Sizehaspricingfactorof"+d);
33}
34}
35/*结果如下:
36SmallSizehaspricingfactorof0.8
37MediumSizehaspricingfactorof1.0
38LargeSizehaspricingfactorof1.0
39ExtraLargeSizehaspricingfactorof1.2
40ExtraExtraLargeSizehaspricingfactorof1.2*/
8. 枚举在switch语句中的用法,见如下代码:
1publicenumColor{
2RED,BLUE,BLACK,YELLOW
3}
4publicstaticvoidmain(String[]args){
5Colorm=Color.BLUE;
6//case语句中引用枚举常量时不需要再加上枚举的类型名了。
7switch(m){
8 caseRED:
9System.out.println("colorisred");
10break;
11caseBLACK:
12System.out.println("colorisblack");
13break;
14caseYELLOW:
15System.out.println("colorisyellow");
16break;
17caseBLUE:
18System.out.println("colorisblue");
19break;
20default:
21System.out.println("colorisunknown");
22break;
23}
24}
9. 和枚举相关的两个容器EnumMap和EnumSet,声明和主要用法如下。
1EnumMap,V>
2EnumSet>
3//CodeExample1
4publicenumState{
5ON,OFF
6};
7publicstaticvoidmain(String[]args){
8//EnumSet的使用
9EnumSetstateSet=EnumSet.allOf(State.class);
10for(States:
stateSet)
11System.out.println(s);
12
13//EnumMap的使用
14EnumMapstateMap=newEnumMap(State.class);
15stateMap.put(State.ON,"isOn");
16stateMap.put(State.OFF,"isoff");
17for(States:
State.values())
18System.out.println(s.name()+":
"+stateMap.get(s));
19}
20
21//CodeExample2
22publicenumSize{
23Small,Medium,Large
24}
25publicstaticvoidmain(Stringargs[]){
26Mapmap=newEnumMap(Size.class);
27map.put(Size.Small,0.8);
28map.put(Size.Medium,1.0);
29map.put(Size.Large,1.2);
30for(Map.Entryentry:
map.entrySet())
31helper(entry);
32}
33privatestaticvoidhelper(Map.Entryentry){
34System.out.println("Mapentry:
"+entry);
35}
10. Java枚举和C++枚举的主要区别为两点,一是C++中的枚举中只能定义常量,主要用于switch子句,二是C++中的枚举常量可以直接和数值型变量进行各种数学运算。
五、反射:
1. Java的反射机制主要表现为四点:
1) 在运行中分析类的能力;
2) 在运行中查看对象;
3) 实现数组的操作代码;
4) 利用Method对象,这个对象很像C++中的函数指针。
注:
Java的基于反射的应用主要用于一些工具类库的开发,在实际的应用程序开发中应用的场景较少。
2. 获取对象的名称(字符串形式)vs通过对象的名称(字符串形式)创建对象实例,见如下代码:
1publicstaticvoidmain(Stringargs[]){
2//1.通过对象获取其字符串表示的名称
3Dated=newDate();
//orClass
extendsDate>c1=d.class;
4Class
extendsDate>c1=d.getClass();
5StringclassName=c1.getName();
6
7//2.通过字符串形式的名称创建类实例。
8className="java.util."+className;
9try{
10Classc2=Class.forName(className);
11//这里用到的newInstance用于创建c2所表示的对象实例,但是必须要求待创建的类实例
12//具有缺省构造函数(无参数),很明显newInstance调用并未传入任何参数用于构造对象。
13Dated2=(Date)c2.newInstance();
14}catch(ClassNotFoundExceptione){
15e.printStackTrace();
16}catch(InstantiationExceptione){
17e.printStackTrace();
18}catch(IllegalAccessExceptione){
19e.printStackTrace();
20}
21}
如果需要通过调用带有参数的构造函数来创建对象实例,需要使用java.lang.reflect.Constructor对象来完成,见如下代码:
1publicstaticvoidmain(Stringargs[]){
2StringclassName="java.util.Date";
3try{
4Classc2=Class.forName(className);
5//找到只接受一个long类型参数的构造器
6Constructorcc=c2.getConstructor(long.class);
7longll=45L;
8//将该Constructor期望的指定类型(long)的参数实例传入并构造Date对象。
9Datedd=(Date)cc.newInstance(ll);
10System.out.println("Date.toString="+dd);
11}catch(Exceptione){
12e.printStackTrace();
13}
14}
3. 遍历一个未知类型的所有域、构造方法和域方法,见如下函数原型:
Field[]getFields();返回指定对象域字段数组,主要包含该类及其超类的所有公有(public)域。
Field[]getDeclaredFields();返回指定对象域字段数组,主要包含该类自身的所有域,包括private等。
Method[]getMethods();返回指定对象域方法数组,主要包含该类及其超类的所有公有(public)域方法。
Method[]getDeclaredMethods();返回指定对象域方法数组,主要包含该类自身的所有域方法,包括private等。
Constructor[]getConstructors();返回指定对象构造函数数组,主要包含该类所有公有(public)域构造器。
Constructor[]getDeclaredConstructors();返回指定对象构造函数数组,主要包含该类所有域构造器。
intgetModifiers();返回一个用于描述构造器、方法或域的修饰符的整型数值,使用Modifier类中的静态方法可以协助分析这个返回值。
StringgetName();返回一个用于描述构造器、方法和域名的字符串。
Class[]getParameterTypes();返回一个用于描述参数类型的Class对象数组。
Class[]getReturnType();返回一个用于描述返回值类型的Class对象。
1privatestaticvoidprintConstructors(Classc1){
2Constructor[]constructors=c1.getDeclaredConstructors();
3for(Constructorc:
constructors){
4Stringname=c.getName();
5System.out.print("");
6Stringmodifiers=Modifier.toString(c.getModifiers());
7if(modifiers.length()>0)
8System.out.print(modifiers+"");
9System.out.print(name+"(");
10
11Class[]paramTypes=c.getParameterTypes();
12for(intj=0;j13if(j>0)
14System.out.print(",");
15System.out.print(paramTypes[j].getName());
16}
17System.out.println(");");
18}
19}
20
21privatestaticvoidprintMethods(Classc1){
22Method[]methods=c1.getDeclaredMethods();
23for(Methodm:
methods){
24ClassretType=m.getReturnType();
25Stringname=m.getName();
26System.out.print("");
27
28Stringmodifiers=Modifier.toString(m.getModifiers());
29if(modifiers.length()>0)
30System.out.print(modifiers+"");
31System.out.print(retType.getName()+""+name+"(");
32Class[]paramTypes=m.getParameterTypes();
33for(intj=0;j34if(j>0)
35System.out.print(",");
36System.out.print(paramTypes[j].getName());
37}
38System.out.println(");");
39}
40}
41
42privatestaticvoidprintFields(Classc1){
43Field[]fields=c1.getDeclaredFields();
44for(Fieldf:
fields){
45Classtype=f.getType();
46Stringname=f.getName();
47System.out.print("");
48Stringmodifiers=Modifier.toString(f.getModifiers());
49if(modifiers.length()>0)
50System.out.print(modifiers+"");
51System.out.println(type.getName()+""+name+";");
52}
53}
54
55publicstaticvoidmain(Stringargs[]){
56Stringname="java.lang.Double";
57try{
58Classc1=Class.forName(name);
59Classsuperc1=c1.getSuperclass();
60Stringmodifier=Modifier.toString(c1.getModifiers());
61if(modifier.length()>0)
62System.out.print(modifier+"");
63
64System.out.print("class"+name);
65if(superc1!
=null&&superc1!
=Object.class)
66System.out.print("extends"+superc1.getName());
67
68System.out.print("\n{\n");
69printConstructors(c1);
70System.out.println();
71printMethods(c1);
72System.out.println();
73printFields(c1);
74System.out.println("}");
75}catch(Exceptione){
76e.printStackTrace();
77}
78}
79/*输出结果如下:
80publicfinalclassjava.lang.Doubleextendsjava.lang.Number
81{
82publicjava.lang.Double(java.lang.String);
83publicjava.lang.Double(double);
84
85publicbooleanequals(