真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java和C++的枚舉與反射有什么不同

這篇文章主要介紹“Java和C++的枚舉與反射有什么不同”,在日常操作中,相信很多人在Java和C++的枚舉與反射有什么不同問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java和C++的枚舉與反射有什么不同”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

成都創(chuàng)新互聯(lián)公司是一家朝氣蓬勃的網(wǎng)站建設(shè)公司。公司專注于為企業(yè)提供信息化建設(shè)解決方案。從事網(wǎng)站開發(fā),網(wǎng)站制作,網(wǎng)站設(shè)計,網(wǎng)站模板,微信公眾號開發(fā),軟件開發(fā),小程序開發(fā),十載建站對咖啡廳設(shè)計等多個領(lǐng)域,擁有多年的網(wǎng)站制作經(jīng)驗。

一、枚舉:

枚舉的是在Java 1.5SE 中開始支持的,以下為Java枚舉的基本概念和應(yīng)用技巧:

1.    所有的enum對象均是由class對象作為底層支持的,該對象繼承自JDK中的Enum,但是該底層類確實final類,既不能再被其他的類繼承。

2.    枚舉的出現(xiàn)完全替代了原有的"public static final"常量表示法,枚舉以一種更加合理、優(yōu)雅和安全的方式替換了原有的方案。其最基本的聲明方式如下:

public enum Color { RED, BLUE, BLACK, YELLOW }

3.    Enum中構(gòu)造函數(shù)的原型為protected Enum(String name, int ordinal),自定義的枚舉對象會將自身的名字以字符串的形式,同時將自己在整個常量從聲明的順序作為超類構(gòu)造函數(shù)的兩個參數(shù)傳給超類并由超類完成必要的初始化,如:RED枚舉常量將調(diào)用super("RED",0)。

4.    枚舉中可以定義構(gòu)造函數(shù)、域方法和域字段,但是枚舉中的構(gòu)造器必須是私有(private)的,如果自定義枚舉中有了自定義的構(gòu)造函數(shù),那么每個枚舉常量在聲明時必須按照自定義構(gòu)造函數(shù)的規(guī)則傳入?yún)?shù)。枚舉對象的構(gòu)造函數(shù)只是在枚舉常量對象聲明的時刻才調(diào)用一次,之后再也不能像普通對象那樣通過new的方法創(chuàng)建,見如下代碼:

public enum Size { SMALL(0.8), MEDIUM(1.0), LARGE(1.2); double pricingFactor; private Size(double p) { pricingFactor = p; } }

注:枚舉常量列表必須寫在最前面聲明,否則編譯器報錯。

5.    可以給自定義枚舉添加域方法,見如下代碼:

public enum Size { SMALL(0.8), MEDIUM(1.0), LARGE(1.2); private double pricingFactor; Size(double p) { pricingFactor = p; } public double getPricingFactor() { return pricingFactor; } }

6.    枚舉中常用域方法:

public enum Size{ SMALL, MEDIUM, LARGE; } public static void main(String[] args){ //兩種獲得枚舉類型的方法 Size s1 = Size.SMALL; //valueOf的函數(shù)原型為> T valueOf(Class enumType,String name) Size s2 = Enum.valueOf(Size.class, "SMALL"); //Size(自定義枚舉)的valueOf方法是Java編譯器在生成字節(jié)碼的時候自動插入的。 Size s3 = Size.valueOf("MEDIUM");//1  //結(jié)果同上,枚舉重載了equals方法 System.out.println("Size.MEDIUM.equals(Enum.valueOf(Size.class, \"MEDIUM\")):"+ Size.MEDIUM.equals(Enum.valueOf(Size.class, "MEDIUM")));  //遍歷枚舉類型中所有的成員,這里應(yīng)用的Size.values方法和Size.valueOf方法 //一樣均是編譯器在生成字節(jié)碼的時候自動插入的。 for(Size s:Size.values()){//2 //ordinal()和name()方法均為Enum提供的方法,返回枚舉常量在聲明時的構(gòu) //造函數(shù)中自動調(diào)用超類構(gòu)造函數(shù)時傳入的自身字符串名和在聲明列表中的序號 System.out.println(s.ordinal()+" "+s.name()+" "+s.toString()); } //compareTo方法缺省比較的是枚舉常量的ordinal()的返回值。 if (s1.compareTo(s3) < 0) System.out.println("Size.SMALL is less than Size.MEDIUM"); }

7.    在枚舉中可以聲明基于特定常量的類主體,見如下代碼:

public enum Size { //Small、ExtraLarge和ExtraExtraLarge均使用自定義的getPricingFactor //方法覆蓋Size提供的缺省getPricingFactor方法。 Small { @Override public double getPricingFactor() { return 0.8; } }, //Medium和Large將使用Size內(nèi)部缺省實現(xiàn)的getPricingFactor方法。 Medium, Large, ExtraLarge { @Override public double getPricingFactor() { return 1.2; } }, ExtraExtraLarge { @Override public double getPricingFactor() { return 1.2; } }; public double getPricingFactor() { return 1.0; } } public static void main(String args[]) { for (Size s : Size.values()) { double d = s.getPricingFactor(); System.out.println(s + " Size has pricing factor of " + d); } } /* 結(jié)果如下: Small Size has pricing factor of 0.8 Medium Size has pricing factor of 1.0 Large Size has pricing factor of 1.0 ExtraLarge Size has pricing factor of 1.2 ExtraExtraLarge Size has pricing factor of 1.2 */

8.    枚舉在switch語句中的用法,見如下代碼:

public enum Color { RED, BLUE, BLACK, YELLOW } public static void main(String[] args) { Color m = Color.BLUE; //case語句中引用枚舉常量時不需要再加上枚舉的類型名了。 switch (m) {     case RED: System.out.println("color is red"); break; case BLACK: System.out.println("color is black"); break; case YELLOW: System.out.println("color is yellow"); break; case BLUE: System.out.println("color is blue"); break; default: System.out.println("color is unknown"); break; } }

9.    和枚舉相關(guān)的兩個容器EnumMap和EnumSet,聲明和主要用法如下。

EnumMap, V>  EnumSet> //Code Example 1 public enum State {  ON, OFF  };  public static void main(String[] args) {  //EnumSet的使用  EnumSet stateSet = EnumSet.allOf(State.class);  for (State s : stateSet) System.out.println(s);   //EnumMap的使用  EnumMap stateMap = new EnumMap(State.class);  stateMap.put(State.ON, "is On");  stateMap.put(State.OFF, "is off");  for (State s : State.values())  System.out.println(s.name() + ":" + stateMap.get(s));  }  //Code Example 2 public enum Size { Small,Medium,Large } public static void main(String args[]) { Map map = new EnumMap(Size.class); map.put(Size.Small, 0.8); map.put(Size.Medium, 1.0); map.put(Size.Large, 1.2); for (Map.Entry entry : map.entrySet()) helper(entry); } private static void helper(Map.Entry entry) { System.out.println("Map entry: " + entry); }

10.    Java枚舉和C++枚舉的主要區(qū)別為兩點,一是C++中的枚舉中只能定義常量,主要用于switch子句,二是C++中的枚舉常量可以直接和數(shù)值型變量進(jìn)行各種數(shù)學(xué)運算。

二、反射:

1.    Java的反射機(jī)制主要表現(xiàn)為四點:

1)    在運行中分析類的能力;

2)    在運行中查看對象;

3)    實現(xiàn)數(shù)組的操作代碼;

4)    利用Method對象,這個對象很像C++中的函數(shù)指針。

注:Java的基于反射的應(yīng)用主要用于一些工具類庫的開發(fā),在實際的應(yīng)用程序開發(fā)中應(yīng)用的場景較少。

2.    獲取對象的名稱(字符串形式) vs 通過對象的名稱(字符串形式)創(chuàng)建對象實例,見如下代碼:

public static void main(String args[]) { //1. 通過對象獲取其字符串表示的名稱  Date d = new Date();   //or Class c1 = d.class; Class c1 = d.getClass();  String className = c1.getName();  //2. 通過字符串形式的名稱創(chuàng)建類實例。 className = "java.util." + className; try { Class c2 = Class.forName(className); //這里用到的newInstance用于創(chuàng)建c2所表示的對象實例,但是必須要求待創(chuàng)建的類實例 //具有缺省構(gòu)造函數(shù)(無參數(shù)),很明顯newInstance調(diào)用并未傳入任何參數(shù)用于構(gòu)造對象。 Date d2 = (Date)c2.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }

如果需要通過調(diào)用帶有參數(shù)的構(gòu)造函數(shù)來創(chuàng)建對象實例,需要使用java.lang.reflect.Constructor對象來完成,見如下代碼:

public static void main(String args[]) { String className = "java.util.Date"; try { Class c2 = Class.forName(className); //找到只接受一個long類型參數(shù)的構(gòu)造器 Constructor cc = c2.getConstructor(long.class); long ll = 45L; //將該Constructor期望的指定類型(long)的參數(shù)實例傳入并構(gòu)造Date對象。 Date dd = (Date)cc.newInstance(ll); System.out.println("Date.toString = " + dd); } catch (Exception e) { e.printStackTrace(); } }

3.    遍歷一個未知類型的所有域、構(gòu)造方法和域方法,見如下函數(shù)原型:

Field[] getFields(); 返回指定對象域字段數(shù)組,主要包含該類及其超類的所有公有(public)域。

Field[] getDeclaredFields();返回指定對象域字段數(shù)組,主要包含該類自身的所有域,包括private等。

Method[] getMethods(); 返回指定對象域方法數(shù)組,主要包含該類及其超類的所有公有(public)域方法。

Method[] getDeclaredMethods();返回指定對象域方法數(shù)組,主要包含該類自身的所有域方法,包括private等。

Constructor[] getConstructors(); 返回指定對象構(gòu)造函數(shù)數(shù)組,主要包含該類所有公有(public)域構(gòu)造器。

Constructor[] getDeclaredConstructors();返回指定對象構(gòu)造函數(shù)數(shù)組,主要包含該類所有域構(gòu)造器。

int getModifiers(); 返回一個用于描述構(gòu)造器、方法或域的修飾符的整型數(shù)值,使用Modifier類中的靜態(tài)方法可以協(xié)助分析這個返回值。

String getName(); 返回一個用于描述構(gòu)造器、方法和域名的字符串。

Class[] getParameterTypes(); 返回一個用于描述參數(shù)類型的Class對象數(shù)組。

Class[] getReturnType(); 返回一個用于描述返回值類型的Class對象。

private static void printConstructors(Class c1) { Constructor[] constructors = c1.getDeclaredConstructors(); for (Constructor c : constructors) { String name = c.getName(); System.out.print(" "); String modifiers = Modifier.toString(c.getModifiers()); if (modifiers.length() > 0) System.out.print(modifiers + " "); System.out.print(name + "(");  Class[] paramTypes = c.getParameterTypes(); for (int j = 0; j < paramTypes.length; ++j) { if (j > 0) System.out.print(","); System.out.print(paramTypes[j].getName()); } System.out.println(");"); } }  private static void printMethods(Class c1) { Method[] methods = c1.getDeclaredMethods(); for (Method m : methods) { Class retType = m.getReturnType(); String name = m.getName(); System.out.print(" ");  String modifiers = Modifier.toString(m.getModifiers()); if (modifiers.length() > 0) System.out.print(modifiers + " "); System.out.print(retType.getName() + " " + name + "("); Class[] paramTypes = m.getParameterTypes(); for (int j = 0; j < paramTypes.length; ++j) { if (j > 0)  System.out.print(", "); System.out.print(paramTypes[j].getName()); } System.out.println(");"); } }  private static void printFields(Class c1) { Field[] fields = c1.getDeclaredFields(); for (Field f : fields) { Class type = f.getType(); String name = f.getName(); System.out.print(" "); String modifiers = Modifier.toString(f.getModifiers()); if (modifiers.length() > 0) System.out.print(modifiers + " "); System.out.println(type.getName() + " " + name + ";"); } }  public static void main(String args[]) { String name = "java.lang.Double"; try { Class c1 = Class.forName(name); Class superc1 = c1.getSuperclass(); String modifier = Modifier.toString(c1.getModifiers()); if (modifier.length() > 0) System.out.print(modifier + " ");  System.out.print("class " + name); if (superc1 != null && superc1 != Object.class) System.out.print(" extends " + superc1.getName());  System.out.print("\n{\n"); printConstructors(c1); System.out.println(); printMethods(c1); System.out.println(); printFields(c1); System.out.println("}"); } catch (Exception e) { e.printStackTrace(); } } /* 輸出結(jié)果如下: public final class java.lang.Double extends java.lang.Number { public java.lang.Double(java.lang.String); public java.lang.Double(double);  public boolean equals(java.lang.Object); public java.lang.String toString(); public static java.lang.String toString(double); public int hashCode(); public static native long doubleToRawLongBits(double); public static long doubleToLongBits(double); public static native double longBitsToDouble(long); public int compareTo(java.lang.Double); public volatile int compareTo(java.lang.Object); public byte byteValue(); public short shortValue(); public int intValue(); public long longValue(); public float floatValue(); public double doubleValue(); public static java.lang.Double valueOf(double); public static java.lang.Double valueOf(java.lang.String); public static java.lang.String toHexString(double); public static int compare(double, double); public boolean isNaN(); public static boolean isNaN(double); public boolean isInfinite(); public static boolean isInfinite(double); public static double parseDouble(java.lang.String);  public static final double POSITIVE_INFINITY; public static final double NEGATIVE_INFINITY; public static final double NaN; public static final double MAX_VALUE; public static final double MIN_NORMAL; public static final double MIN_VALUE; public static final int MAX_EXPONENT; public static final int MIN_EXPONENT; public static final int SIZE; public static final java.lang.Class TYPE; private final double value; private static final long serialVersionUID; } */

4.    通過反射編寫泛型數(shù)組代碼,見如下代碼比較:

static Object[] badArrayGrow(Object[] a) { int newLength = a.length * 11 / 10 + 10; //該對象數(shù)組的在創(chuàng)建時是基于Object的,所以返回后, //再裝回其他類型數(shù)組時將會拋出ClassCastException的異常。 Object[] newArray = new Object[newLength]; System.arraycopy(a,0,newArray,0,a.length); return newArray; }  static Object goodArrayGrow(Object a) {//這里的參數(shù)務(wù)必為Object,而不是Object[]  Class c1 = a.getClass(); if (!c1.isArray())  return null; //這里用于獲取數(shù)組成員的類型 Class componentType = c1.getComponentType(); //獲取數(shù)組的長度。 int length = Array.getLength(a); int newLength = length * 11 / 10 + 10; //通過數(shù)組成員的類型和新的長度值來創(chuàng)建一個和參數(shù)類型相同的數(shù)組, //并增加他的空間,***再返回。 Object newArray = Array.newInstance(componentType,newLength); System.arraycopy(a,0,newArray,0,length); return newArray; }

5.    在運行時使用反射的對象或動態(tài)調(diào)用反射之后的方法。

1)    獲取域字段和設(shè)置域字段:

public void testField() { Employee harry = new Employee("Harry Hacker",35000,10); Class c1 = harry.getClass(); Field f = c1.getDeclaredField("name"); //由于name字段有可能是Employee類的私有域字段,如果直接調(diào)用會致使JVM //拋出安全異常,為了避免該異常的發(fā)生,需要調(diào)用下面的語句來得以保證。 f.setAccessible(true); Object v = f.get(harry); System.out.println(v); }

2)    通過Method的invoke函數(shù)動態(tài)調(diào)用反射后的方法:

該方式有些類似于C#的委托(delegate)和C++的函數(shù)指針。

public int add(int param1, int param2) {  return param1 + param2;  }   public static void main(String[] args) throws Exception {  Class classType = MyTest.class;  Object myTest = classType.newInstance();  Method addMethod = classType.getMethod("add",int.class,int.class); //如果add為靜態(tài)方法,這里的***個參數(shù)傳null Object result = addMethod.invoke(myTest, 100,200);  System.out.println(result);  }

6.    C++自身并沒有提供像Java這樣完備的反射機(jī)制,只是提供了非常簡單的動態(tài)類型信息,如type_info和typeid。然而在一些C++的第三方框架類庫中提供了類似的功能,如MFC、QT。其中MFC是通過宏的方式實現(xiàn),QT是通過自己的預(yù)編譯實現(xiàn)。在目前的主流開發(fā)語言中,也只有C#提供的反射機(jī)制可以和Java的相提并論。

到此,關(guān)于“Java和C++的枚舉與反射有什么不同”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
本文名稱:Java和C++的枚舉與反射有什么不同
文章轉(zhuǎn)載:http://weahome.cn/article/psssed.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部