java.lang → Boolean

是什么

Boolean 类是将 boolean 基本类型进行包装。类型为 Boolean 的对象包含一个单一属性 value,其类型为 boolean。
此外还提供了许多将 boolean 转换为 String、String 转换为 boolean,以及其他一些方法。

构造器

有两个构造器

public Class Boolean {
public static final Boolean TRUE = new Boolean(true); public static final Boolean FALSE = new Boolean(false); public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean"); private final boolean value; public Boolean(boolean value) {
this.value = value;
} public Boolean(String s) {
this(parseBoolean(s));
}
}

我们可以看到在内部维护了一个 boolean 类型的 value,在我们调用构造器的时候会将 value 给赋值。

还可以看到内部还有三个常量其中两个是 TRUE、FALSE 分别代表布尔值的两个状态,这样我们在使用的时候就可以直接用而不需要去构建一个。

还有一个 TYPE 是接收了 Class.getPrimitiveClass("boolean"); 的返回值,我们跟进去可以看到 getPrimitiveClass 是一个 native 方法。

static native Class<?> getPrimitiveClass(String name);

我们直接查看 openJDK 中对应的 Class.c 文件可以发现对应的方法 Java_java_lang_Class_getPrimitiveClass

JNIEXPORT jclass JNICALL
Java_java_lang_Class_getPrimitiveClass(JNIEnv *env,
jclass cls,
jstring name)
{
const char *utfName;
jclass result; if (name == NULL) {
JNU_ThrowNullPointerException(env, 0);
return NULL;
} utfName = (*env)->GetStringUTFChars(env, name, 0);
if (utfName == 0)
return NULL; result = JVM_FindPrimitiveClass(env, utfName); (*env)->ReleaseStringUTFChars(env, name, utfName); return result;
}

我们可以看到 JVM 会根据我们传递的 "boolean" name 字符串来调用 JVM_FindPrimitiveClass 来获取到 jclass,返回到 java 层则为 Class.

并且如果常量 TYPE 在执行到 toString() 时还是会调用到 native 方法。如下

public String toString() {
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
+ getName();
} public String getName() {
String name = this.name;
if (name == null)
// 会调用到 getName0();
this.name = name = getName0();
return name;
} private native String getName0();

我们会发现最终会调用到 getName0() 这个 native 方法。所以我们继续去看 C 文件

static JNINativeMethod methods[] = {
{"getName0", "()" STR, (void *)&JVM_GetClassName},
{"getSuperclass", "()" CLS, NULL},
{"getInterfaces0", "()[" CLS, (void *)&JVM_GetClassInterfaces},
{"getClassLoader0", "()" JCL, (void *)&JVM_GetClassLoader},
{"isInterface", "()Z", (void *)&JVM_IsInterface},
{"getSigners", "()[" OBJ, (void *)&JVM_GetClassSigners},
{"setSigners", "([" OBJ ")V", (void *)&JVM_SetClassSigners},
{"isArray", "()Z", (void *)&JVM_IsArrayClass},
{"isPrimitive", "()Z", (void *)&JVM_IsPrimitiveClass},
{"getComponentType", "()" CLS, (void *)&JVM_GetComponentType},
{"getModifiers", "()I", (void *)&JVM_GetClassModifiers},
{"getDeclaredFields0","(Z)[" FLD, (void *)&JVM_GetClassDeclaredFields},
{"getDeclaredMethods0","(Z)[" MHD, (void *)&JVM_GetClassDeclaredMethods},
{"getDeclaredConstructors0","(Z)[" CTR, (void *)&JVM_GetClassDeclaredConstructors},
{"getProtectionDomain0", "()" PD, (void *)&JVM_GetProtectionDomain},
{"getDeclaredClasses0", "()[" CLS, (void *)&JVM_GetDeclaredClasses},
{"getDeclaringClass0", "()" CLS, (void *)&JVM_GetDeclaringClass},
{"getGenericSignature0", "()" STR, (void *)&JVM_GetClassSignature},
{"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations},
{"getConstantPool", "()" CPL, (void *)&JVM_GetClassConstantPool},
{"desiredAssertionStatus0","("CLS")Z",(void *)&JVM_DesiredAssertionStatus},
{"getEnclosingMethod0", "()[" OBJ, (void *)&JVM_GetEnclosingMethodInfo},
{"getRawTypeAnnotations", "()" BA, (void *)&JVM_GetClassTypeAnnotations},
};

我们可以看到这个数组的第一行 getName0 就被定义为了 JVM_GetClassName 的函数。大家还记得当时 Object 文章里类似的地方吗,是的没错 Class 类中也有 registerNatives 的本地方法来注册对应的方法。

public final class Class<T> implements java.io.Serializable,GenericDeclaration,Type,
AnnotatedElement { private static native void registerNatives();
static {
registerNatives();
}
}

好了我们继续来看 getName0 被定义为对应的 JVM_GetClassName 函数后。最终的 JVM_GetClassName 实现函数是下面展示的.

JVM_ENTRY(jstring, JVM_GetClassName(JNIEnv *env, jclass cls))
assert (cls != NULL, "illegal class");
JVMWrapper("JVM_GetClassName");
JvmtiVMObjectAllocEventCollector oam;
ResourceMark rm(THREAD);
const char* name;
if (java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
// 注意这一行函数里会去 type2name_tab 数组里去寻找
name = type2name(java_lang_Class::primitive_type(JNIHandles::resolve(cls)));
} else {
// Consider caching interned string in Klass
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
assert(k->is_klass(), "just checking");
name = k->external_name();
}
oop result = StringTable::intern((char*) name, CHECK_NULL);
return (jstring) JNIHandles::make_local(env, result);
JVM_END

我们可以看到第八行会去调用 type2name 函数,最终根据一个数组获得对应的名称,比如这里下标为4,则名称为”boolean”。

const char* type2name_tab[T_CONFLICT+1] = {
NULL, NULL, NULL, NULL,
"boolean",
"char",
"float",
"double",
"byte",
"short",
"int",
"long",
"object",
"array",
"void",
"*address*",
"*narrowoop*",
"*conflict*"
};

重要方法

parseBoolean

public static boolean parseBoolean(String s) {
// 判断参数 s 是否不为空并且是 "true" 字符串
return ((s != null) && s.equalsIgnoreCase("true"));
}

valueOf

public static Boolean valueOf(boolean b) {
// 三目表达式没什么好说的
return (b ? TRUE : FALSE);
}

toString

public static String toString(boolean b) {
// 三目表达式没什么好说的
return b ? "true" : "false";
} public String toString() {
return value ? "true" : "false";
}

hashCode

public static int hashCode(boolean value) {
// 即 true 返回 1231 而 false 返回 1237
return value ? 1231 : 1237;
}

equals

public boolean equals(Object obj) {
// 方法就是先判断是不是从 Boolean 实例化出来的,然后再继续比较是不是相等。
if (obj instanceof Boolean) {
return value == ((Boolean)obj).booleanValue();
}
return false;
}

getBoolean

public static boolean getBoolean(String name) {
boolean result = false;
try {
// 从系统环境中获取指定 name 如果失败则返回 false
result = parseBoolean(System.getProperty(name));
} catch (IllegalArgumentException | NullPointerException e) {
}
return result;
}

compareTo

public int compareTo(Boolean b) {
return compare(this.value, b.value);
} public static int compare(boolean x, boolean y) {
// 如果 boolean 相等则返回 0 否则 x 为真返回 1 为假返回 -1
return (x == y) ? 0 : (x ? 1 : -1);
}

逻辑运算

public static boolean logicalAnd(boolean a, boolean b) {
return a && b;
} public static boolean logicalOr(boolean a, boolean b) {
return a || b;
} public static boolean logicalXor(boolean a, boolean b) {
return a ^ b;
}

上面三个方法也没啥好说的大家自己看。

java.lang -> Boolean的更多相关文章

  1. JDK1.7.0_45源码阅读<java.lang.Boolean>

    本文适合的人群 其实感觉写这个标题的内容没有必要,只要你觉得对你有帮助那么就适合你,对你没帮助那么就不适合你.毕竟我不是专业作者,但咱会尽力的.其实最重要的一点是我不希望浪费您宝贵时间. 简要把内容在 ...

  2. java.lang.Boolean为null时

    public class TestBooleanNull { public static void main(String[] args) { if (test()) { System.out.pri ...

  3. Cannot convert 0 of type class java.lang.Integer to class java.lang.Boolean

    org.apache.catalina.core.ApplicationDispatcher invoke SEVERE: Servlet.service() for servlet jsp thre ...

  4. java.lang.Boolean 类源码解析

    Boolean源码比较简单. public final class Boolean implements java.io.Serializable, Comparable<Boolean> ...

  5. jdk源码分析——java.lang.Boolean

      1.Boolean类里面的2个静态变量. Boolean类,直接声明了2个静态变量,TRUE 和 FALSE,指向2个对象.     public static final Boolean TRU ...

  6. java.lang.Boolean.compareTo()方法实例

    compareTo接口 Comparable<Boolean>指定以下接口 参数 b - 布尔实例进行比较 返回值 方法返回 0 - 如果该对象表示相同的布尔值作为参数 一个正数值 - 如 ...

  7. Unknown return value type [java.lang.Boolean]] with root cause

    添加@responsebody 为什么呢 ? 因为在进行ajax传输的时候  我已指定传输的类型为 json数据类型 要是不加的话 它只是Boolean类型 而不是json类型

  8. java.lang.Boolean.valueOf(String s)

    简单说,就是s为true(这四个字母大小写任意)时,返回值为true,否则为false public class one { public static void main(String[] args ...

  9. java.lang基础数据类型boolean、char、byte、short、int、long、float、double (JDK1.8)

    java.lang.Boolean public static int hashCode(boolean value) { return value ? 1231 : 1237; } JDK 1.8新 ...

随机推荐

  1. sshpass非交互SSH密码验证

    1.yum安装yum install sshpass -y1.1编译安装yum install wget -ywget http://sourceforge.net/projects/sshpass/ ...

  2. var、let、const的区别

    var.let.const的区别 var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问. let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问. const用来定义常量,使 ...

  3. What is one-hot?

    SEO: libtorch 如何 OneHot ? torch OneHot 源代码 ? https://www.tensorflow.org/api_docs/python/tf/one_hot 最 ...

  4. qt 如何使用私有类?

    在模块后面加上 -private 关键字,例如 widgets-private 然后 qmake 让配置文件运行一下. 在使用 QStackedLayout 布局并设置 QStackedLayout: ...

  5. 快速部署业务类为webapi服务

    接着前一篇博文,将接口快速打包固定请求格式,不需要修改代码,可以自动完成接口调用,实际上就是生成了一个接口的代理类. 那么仅仅是接口请求代理,没有服务端怎么行?所以需要将实现接口的类部署为webapi ...

  6. 【新手向】一个超简单的jquery.mCustomScrollbar滚动条插件Demo

    <script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script> < ...

  7. ajax请求超时解决方案

    设置timeout的时间,通过检测complete时status的值判断请求是否超时,如果超时执行响应的操作. var ajaxTimeoutTest=$.ajax({ url:'',//请求地址 t ...

  8. 一些常见的js校验

    今天有时间来总结一下那些常用的js校验: vernull = function(value){//非空校验 if(value.trim(value).length == 0){ return fals ...

  9. 20180329-layoutSubviews的调用机制

    如果你想强制更新布局,不要直接调用此方法,你可以调用setNeedsLayout方法,如果你想立即显示你的views,你需要调用layoutIfNeed方法 layoutSubviews作用: lay ...

  10. CentOS7.6系统安装zabbix3.4.8客户端

    一.     准备安装包 将本地的zabbix-3.4.8软件包上传至服务器, 二.     安装依赖包 安装依赖包:yum install gcc* pcre* psmisc -y 三.     安 ...