GVKun编程网logo

Enum.valueOf(String)方法从何而来?(enum的valueof方法)

25

对于想了解Enum.valueOf的读者,本文将提供新的信息,我们将详细介绍String方法从何而来?,并且为您提供关于CephRGW的usage数据从何而来?、javaindexof(Strings

对于想了解Enum.valueOf的读者,本文将提供新的信息,我们将详细介绍String方法从何而来?,并且为您提供关于Ceph RGW的usage数据从何而来?、java indexof(String str)方法的复杂性、Java String.valueOf(null)引发NPE,但是Object a = null;String.valueOf(a)返回'null'、Javadoc 1.5和1.6中缺少enum.valueOf(String name)的有价值信息。

本文目录一览:

Enum.valueOf(String)方法从何而来?(enum的valueof方法)

Enum.valueOf(String)方法从何而来?(enum的valueof方法)

在Java SE 7中(并且很可能在以前的版本中),Enum类的声明如下:

 public abstract class Enum<E extends Enum<E>> extends Object implements Comparable<E>, Serializable

Enum类具有带有此签名的静态方法:

  T static<T extends Enum<T>> valueOf(Class<T> enumType, String name)

但是没有静态方法:valueOf(String)在Enum类中定义,也不在Enum所属的层次结构中。

问题是valueOf(String)从哪里来的?它是语言的功能,即编译器中内置的功能吗?

答案1

小编典典

该方法由编译器隐式定义。

从文档中:

请注意,对于特定的枚举类型T,可以使用对该枚举上隐式声明的公共静态T
valueOf(String)方法来代替此方法,以从名称映射到相应的枚举常量。可以通过调用该类型的隐式公共静态T []
values()方法来获取枚举类型的所有常量。

根据Java语言规范的第8.9.2节:

另外,如果E是枚举类型的名称,则该类型具有以下隐式声明的静态方法:

/*** Returns an array containing the constants of this enum * type, in the order they''re declared.  This method may be* used to iterate over the constants as follows:**    for(E c : E.values())*        System.out.println(c);** @return an array containing the constants of this enum * type, in the order they''re declared*/public static E[] values();/*** Returns the enum constant of this type with the specified* name.* The string must match exactly an identifier used to declare* an enum constant in this type.  (Extraneous whitespace * characters are not permitted.)* * @return the enum constant with the specified name* @throws IllegalArgumentException if this enum type has no* constant with the specified name*/public static E valueOf(String name);

Ceph RGW的usage数据从何而来?

Ceph RGW的usage数据从何而来?

uRGW 的Usage信息是如何获取到的? 获取RGW的Usage信息,主要是来自于rgw_admin.cc中的函数:RGWUsage::show()。 这个函数定义在rgw/rgw_usage.h,实现于rgw/rgw_usage.cc 在文件rgw/rgw_usage.cc中可以看到函数的实现。 RGWUsage::show() 输入参数: RGWRados ×store (RGWRados类定义在rgw/rgw_rados.h中,) string& uid (用户名) uint64_t start_epoch(开始的时间) uint64_t end_epoch (结束的时间) ......

从store结构体中调用函数read_usage() 转到rgw/rgw_rados.h中,可以看到read_usage()的声明 在rgw/rgw_rados.cc中可以查看到read_usage()函数的实现。 可以看到read_usage()函数调用的是cls_obj_usage_log_read()。 cls_obj_usage_log_read()调用的是cls_rgw_usage_log_read() 在cls/rgw/cls_rgw_client.cc的249行:cls_rgw_usage_log_read()这个函数里: bufferlist in, out ::encode(call, in) 对bufferlist in进行编码处理,在函数exec中执行。 map<rgw_user_bucket, rgw_usage_log_entry> usage; void encode(bufferlist& bl) { ::encode()//表示这是一个全局函数。用于和局部或者成员函数来区分。 } iter是一个bufferlist迭代器类型。

io_ctx.exec是一个插件的动态加载函数,加载的函数是rgw_user_usage_log_read(),参数分别是in和out。 执行rgw_user_uage_log_read()函数实际上读取的真正的用户使用信息,将结果返回到out这个bufferlist中去。 然后从out中解码用户使用信息,将结果保存到result。 最终,result.usage被保存到了usage中。(由于usage是一个map<rgw_user_bucket, rgw_usage_log_entry>类型的引用,所以,此时就相当于直接修改了usage变量。) 也就是将结果保存到了usage中。

以上是各个函数的调用关系 当函数cls_rgw_usage_log_read()「rgw/cls_rgw_client.cc:249line」返回后,

返回到了调用它的函数RGWRados::cls_obj_usage_log_read()「rgw/rgw_rados.cc:6021line」 此时,已经将参数usage进行了设置。

然后,函数RGWRados::cls_obj_usage_log_read()继续返回,返回到调用它的函数:RGWRados::read_usage()函数。 在RGWRados::read_usage()这个函数中,会在循环条件之下,反复调用cls_obj_usage_log_read()这个函数。

其中,作为存储usage的相关数据结构就是map<rgw_user_bucket, rgw_usage_log_entry> 这是一个复合的数据结构, rgw_usage_log_entry

在io_ctx.exec中调用rgw_user_usage_log_read(),「这是一个封装在插件中的函数」 前一行的::encode(),是将call这个数据结构执行序列化操作,并将序列化操作放到in这个bufferlist中。 假设现在已经将call这个数据结构序列化到了in这个bufferlist中了。进入到rgw_user_usage_log_read()「位于cls/rgw/cls_rgw.cc:1199line」 这个函数的参数正好是bufferlist类型的in和out。 「可以看出,之前的call(rgw/cls_rgw_client.cc:257line)和这里的op是同一个数据类型。 1213 line的ret_info和rgw/cls_rgw_client.cc:269line的result也是同样的数据类型。」

在rgw_user_usage_log_read()函数中,首先对参数in进行反序列化操作,「即就是decode(op, in_iter)」.

反序列化后的结果保存在了op「类型rgw_cls_usage_log_read_op,和之前的call是一个类型的」 随后,使用一个map集合类型的指针变量usage指向了ret_info.usage「ret_info类型是rgw_cls_usage_log_read_ret,和result一致」 max_entries设置了最多能记录多少项。

函数usage_iterate_range(...,(void *)usage)最后是一个指针类型的参数,从后面的代码可以肯定,此函数修改了usage指示的内存地址内容。 而usage指示的内存地址如前所述,恰好是ret_info.usage指示的地址,所以usage_iterate_range()修改的是ret_info.usage的内容, 随后,下一行的encode执行序列化操作,将ret_info内容序列化到out中去。「这里也是间接的修改了out这个bufferlist内存区。」 最终,out指示的bufferlist内存区就存放了user_usage的内容。

现在,唯一还不明了的就是usage_iterate_range()这个函数了。 此函数位于cls/rgw/cls_rgw.cc:1099line 原型:static int usage_iterate_range(cls_method_context_t hctx, uint64_t start, uint64_t end, string& user, string& key_iter, uint32_t max_entries, bool *truncated, int (*cb)(cls_method_context_t, const string&, rgw_usage_log_entry&, void *), void *param)

再来看看位于1199行是如何调用int usage_iterate_range() 参数列表中依次是:hctx,开始的周期,结束周期,所有者,iter(?),最大记录项数量,是否分段,函数指针指向 usage_log_read_cb(), usage指针,指向了ret_info.usage。 即:hctx, op.start_epoch, op.end_epoch, op.owner, iter, max_entries, &ret_info.truncated, usage_log_read_cb, (void )usage /*******************************************************

****************************************************************************/

usage_record_prefix_by_time() usage_record_prefix_by_user() 这两个函数都是相当于在key这个字符串前面添加一些前缀比如时间或者user而已。

关键是cb指针所指向的函数。即就是:usage_log_read_cb() usage_log_read_cb的函数原型是(1189行): static int usage_log_read_cb(cls_method_context_t hctx, const string& key, rgw_usage_log_entry& entry, void *param) 这是一个静态函数。 在函数中usage_log_read_cb() 中,初始化了一个对象ub(entry.owner, entry.bucket) 但是,目前还有一个疑问,所取得的数据到底是从哪里获取的?

usage得到的那些信息,最初的来源就是从函数cls_cxx_map_get_vals() 「./objclass/class_api.cc」 「反正在cls_cxx_map_get_vals()中执行了一些乱七八糟的操作」就把值交给了keys,keys解码,将usage数据放到了

usage的原始数据从何而来,也就是记录的数据又是从哪里得到的? 参见rgw/rgw_log.cc:167,函数log_usage()

java indexof(String str)方法的复杂性

java indexof(String str)方法的复杂性

java indexof(Stringstr)方法的复杂性是什么?我的意思是,有像KMP这样的字符串匹配算法可以在线性时间内运行。我正在实现一个需要在非常大的字符串中搜索大子字符串的系统,因此我可以使用java
indexof(String str)方法还是应该实现KMP。

答案1

小编典典

在Java的复杂执行的indexOfO(m*n)其中nm分别搜索字符串和模式的长度。

您可以采取的措施来提高复杂性,例如使用Boyer-
More算法来智能地跳过比较字符串中与模式不匹配的逻辑部分的比较。

Java String.valueOf(null)引发NPE,但是Object a = null;String.valueOf(a)返回'null'

Java String.valueOf(null)引发NPE,但是Object a = null;String.valueOf(a)返回'null'

是否存在以下行为的逻辑语言设计类型的解释(Java 7和我怀疑较早的版本):

    Object  a = null;    String as = String.valueOf(a);              // as is assigned "null"    System.out.println(as+":"+as.length());     // prints: "null:4"    System.out.println ( String.valueOf(null)); // NPE

答案1

小编典典

在statement中System.out.println(String.valueOf(null));有一个method的调用publicstatic String valueOf(char data[]),其源代码如下:

public static String valueOf(char data[]) {  return new String(data);}

那就是为什么你得到 NPE

另一方面,在statement中Object a = null; String as =String.valueOf(a);有一个method的调用public static String valueOf(Objectobj),其源代码如下:

public static String valueOf(Object obj) {    return (obj == null) ? "null" : obj.toString();}

这就是为什么您得到 “空” 而不是 NPE的原因


Java语言规范中的一些理论问题:15.12.2.5选择最具体的方法

如果多个成员方法既可访问又可应用于方法调用,则必须选择一个成员方法来为运行时方法分派提供描述符。 Java编程语言使用选择 最具体 方法的规则。

A char[]是类型Object,但不是全部Object都是类型char[]。型char[]更具体的
比对象和作为Java语言规范所描述的,String.valueOf(char[])过载被选择在这种情况下。

编辑

还值得一提的是伊恩·罗伯茨([IanRoberts提到的内容(在下面的评论中):

这是需要注意的重要的是它的,如果没有一个统一的超载比所有其他更具体的编译错误-
如果有一个valueOf(String)方法,以及valueOf(Object)
valueOf(char[])随后的非类型化的调用String.valueOf(null) 是不明确

Javadoc 1.5和1.6中缺少enum.valueOf(String name)

Javadoc 1.5和1.6中缺少enum.valueOf(String name)

这可能是一个愚蠢的问题,但是我正在使用method enum.valueOf(Stringname)。那里没问题,只是当我检查javadoc以了解有关此方法的更多信息时,我找不到它。有Javadoc的,valueOf(Class<T>enumType, String name)但没有一个 enum.valueOf(String name)(这表明不存在具有此签名的方法-
但显然它存在)。

我在这里遗漏了什么吗,或者这是API的javadoc中的一个疏漏?

谢谢

答案1

小编典典

没有方法Enum.valueOf(String)但是,每个方法enum都有一个由编译器生成的values()and
valueOf(String)方法,这些都已记录在案。它们是静态方法,因此无法在超类或接口中覆盖或定义它们。

Enum e = Enum.valueOf(""); // this doesn''t compile

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.State.html#values%28%29

http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.State.html#values%28%29

在Java 5.0、6或7中相同。

对于Java 5.0
http://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#8.9(搜索值)对于Java
7 http://docs.oracle.com/javase/规格/ JLS / SE7 / HTML /
JLS-8.html#JLS-8.9.2通过@kapep提供

关于Enum.valueOfString方法从何而来?的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于Ceph RGW的usage数据从何而来?、java indexof(String str)方法的复杂性、Java String.valueOf(null)引发NPE,但是Object a = null;String.valueOf(a)返回'null'、Javadoc 1.5和1.6中缺少enum.valueOf(String name)的相关信息,请在本站寻找。

本文标签: