java.lang.boolean_java.lang -> Boolean

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 TYPE = (Class) 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 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;

}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值