精华内容
下载资源
问答
  • 今天使用Java包装类和基本类型做比较的时候发现了包装本身存在的坑,参考的JDK版本是1.8.0_121,下面是例子代码:Short packShort=1;short baseShort=1;Integer packInt=1;int baseInt=1;//用Short的equals()方法...

    今天使用Java的包装类和基本类型做比较的时候发现了包装本身存在的坑,参考的JDK版本是1.8.0_121,下面是例子代码:

    Short packShort=1;

    short baseShort=1;

    Integer packInt=1;

    int baseInt=1;

    //用Short的equals()方法与short进行比较

    System.out.println(packShort.equals(baseShort));

    //用==比较Short和short

    System.out.println(packShort==baseShort);

    //用Short的equals()方法与int进行比较

    System.out.println(packShort.equals(baseInt));

    //用Short的equals()方法与Integer进行比较

    System.out.println(packShort.equals(packInt));

    //用==比较Short和int

    System.out.println(packShort==baseInt);

    //用==比较Short和Integer,不能进行比较,类型不同

    //System.out.println(packShort==packInt);

    代码的运行结果如下:

    true

    true

    false

    false

    true

    先不分析运行结果,大家可以先看一下Short中的equals()源码:

    public boolean equals(Object obj) {

    if (obj instanceof Short) {

    return value == ((Short)obj).shortValue();

    }

    return false;

    }

    在Integer中equals()代码类似,有兴趣可以自行去看一下,这里就不重复了。以下是结果分析:

    用Short的equals()方法与short进行比较的时候,short类型会被判断为是Short类型的实例,然后两个对象都会被转化为基本类型用==进行比较,所以结果为true。

    用==比较Short和short的时候,Short类型对象被拆箱(转为short基本类型),所以结果为true。

    用Short的equals()方法与int进行比较的时候,由于类型判断那里就已经为false了,直接返回false。

    用Short的equals()方法与Integer进行比较的时候,与用Short的equals()方法与int进行比较的时候同样的原因,返回结果为false。

    用==比较Short和int的时候,Short首先是进行了拆箱(转为short基本类型),然后是自动提升类型(转为int),之后才进行比较,所以结果为true。

    展开全文
  • 我总结了Java数据比较主要有以下要点:1.基本类型和基本类型对比;...基本类型和基本类型对比基本类型和基本类型的比较,因为不是对象所以没有equal方法也没有所谓的引用地址,所以只能”==“来比较它们本身的值。i...

    我总结了Java数据比较主要有以下要点:

    1.基本类型和基本类型对比;

    2.基本类型和包装类型比较;

    3.包装类型和包装类型比较;

    4.”==“与”equal“比较方式;

    5.[-128,127]与非[-128,127]范围的数据比较;

    6.String包装类型的比较。

    基本类型和基本类型对比

    基本类型和基本类型的比较,因为不是对象所以没有equal方法也没有所谓的引用地址,所以只能”==“来比较它们本身的值。

    int a = 127;int b = 127;

    System.out.println("a==b, result:" + (a == b)); //a==b, result:true

    基本类型与包装类型比较

    凡是基本类型和包装类型比较都会触发包装类型自动拆箱的操作,最终还是比较本身的值。

    int a = 127;

    Integer b= 127;

    System.out.println("a==b, result:" + (a == b)); //a==b, result:true

    下面的情况与上面的类似,只不过Java在处理时少了自动装箱的那一步,后面的拆箱比较是一样的。

    int a = 127;

    Integer b= new Integer(127);

    System.out.println("a==b, result:" + (a == b)); //a==b, result:true

    包装类型和包装类型比较

    这里还是暂时只讨论”==“方式的比较,包装类型之间采用”==“比较的是对象的地址。

    包装类型和包装类型比较结果会受包装类型对象的创建方式的影响,如”xxx.valueOf()“还是”new xxx()“方式。

    xxx.valueOf()方式创建对象:这种方式Java遇到-128~127的值,会先去缓存池中根据值查找看是否有已存在的对象,如果有就直接将对象地址返回,如果没有则创建。所以下面的例子中a和b的地址都是同一个对象地址,所以相等。

    Integer a = Integer.valueOf(127);

    Integer b= Integer.valueOf(127);

    System.out.println("a==b, result:" + (a == b)); //a==b, result:true

    new xxx()方式创建对象:这种方式Java不会检查缓存池而是直接new一个新的对象,所以下面例子的两个对象的地址肯定是不相等的。

    Integer a = new Integer(127);

    Integer b= new Integer(127);

    System.out.println("a==b, result:" + (a == b)); //a==b, result:false

    "=="与"equal"比较方式

    equals属于包装类型对象的方法,Java默认equals方法是比较值,当然用户也可以重写该方法。

    Integer a = new Integer(127);

    Integer b= new Integer(127);

    System.out.println("a==b, result:" + (a.equals(b))); // a==b, result:true

    Integer a = new Integer(127);

    int b = 127;

    System.out.println("a==b, result:" + (a.equals(b))); // a==b, result:true

    ”==“相对于equals比较复杂,从上面的例子可以看出,除了”包装类型和包装类型“是比较地址,其它情况都是比较值。

    [-128,127]与非[-128,127]范围的数据比较

    上面的范围不是绝对的,用户是可以对JVM进行配置的。

    当对象的值在[-128,127]范围内,Java会检查缓存池,如果有该对象就直接返回,如果没有则创建。如果范围为非[-128,127],那么Java不会检查。

    可以总结的经验是当用户比较的是对象的地址才需要考虑值的范围是否在[-128,127],如果是比较值,那么不用考虑。

    String包装类型的比较

    String只有包装类型,没有基本类型,所以只讨论包装类型之间的比较。这里之所以将String单独拿出来讨论是因为String为字符串与数值类型的包装对象有点不一样,它有常量池还有字符串拼接等情况都会影响它是否创建新对象。

    所以String的比较就留到下一篇文章再写了。

    展开全文
  • 而且还需要提供一个包装类和基本数据类型的比较方法。 准备知识 1、int.class Integer.class Integer.class 是 int.class 的包装类,如果两者直接 == 比较,返回是 false,原理是因为 Integer 的 class 内存...

    需求

    需要获取一个 Method(java的函数对象) 的返回值类型是否为基本数据类型和何种基本数据类型,然后需要创建一个默认值返回。因此使用反射处理,并且 java 基本数据类型有它的包装类,所以还需要提供一个包装类和其基本数据类型的比较方法。

    准备知识

    1、int.class   Integer.class

    Integer.class 是 int.class 的包装类,如果两者直接 Integer.class == int.class 比较,返回是 false,原理是因为 Integer 的 class 内存地址和 int 的 class 内存地址不同,具体可以在 jvm 源码看到:

    JVM_QUICK_ENTRY(jboolean, JVM_IsPrimitiveClass(JNIEnv *env, jclass cls))
      JVMWrapper("JVM_IsPrimitiveClass");
      oop mirror = JNIHandles::resolve_non_null(cls);
      // 这个地方访问 class 镜像
      return (jboolean) java_lang_Class::is_primitive(mirror);
    JVM_END
    
    // 通过 offset 找出这个 class 的元数据的内存地址是否为空
    bool java_lang_Class::is_primitive(oop java_class) {
      // should assert:
      //assert(java_lang_Class::is_instance(java_class), "must be a Class object");
      bool is_primitive = (java_class->metadata_field(_klass_offset) == NULL);

    在 Integer.TYPE 的属性字段可以看出,TYPE 这个属性单独存放了 int.class,所以两者进行比较时候,是因为 他们的 class 内存地址不同 而返回 false:

    public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
    

    getPrimitiveClass 是底层 native 方法,调用时需要 setAccessible(true) 暴力反射,因为方法访问权限是 default :

    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;
        // 这个地方查找相应的 class
        result = JVM_FindPrimitiveClass(env, utfName);
    
        (*env)->ReleaseStringUTFChars(env, name, utfName);
    
        return result;
    }
    

    然后通过 监控,到当前线程堆里面找它的 class:

    JVM::JVM_ENTRY(jclass, JVM_FindPrimitiveClass(JNIEnv* env, const char* utf))
      JVMWrapper("JVM_FindPrimitiveClass");
      oop mirror = NULL;
      BasicType t = name2type(utf);
      if (t != T_ILLEGAL && t != T_OBJECT && t != T_ARRAY) {
        mirror = Universe::java_mirror(t);
      }
      if (mirror == NULL) {
        THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), (char*) utf);
      } else {
        return (jclass) JNIHandles::make_local(env, mirror);
      }
    JVM_END

    2、org.apache.commons.lang.ClassUtils

    对,用这个工具包就好,省事很多。

    maven工程引入

                <dependency>
                    <groupId>commons-lang</groupId>
                    <artifactId>commons-lang</artifactId>
                    <version>2.4</version>
                </dependency>

    3、具体代码

    如果两个未知的 Class 传入的时候,如果是 Java 八中基本数据类型,怎么去判断 Class01  Class02 哪个基本数据类型或者封装类,然后忽略基本类型和封装类进行比较呢?

    可以画图理解,当 直接调用 class01 ==  class02 时候

    class01 \ class02 封装类 基本数据类型
    封装类 true false
    基本数据类型 false true

    那么如果 class01 == class02 为 false, 两者之间有一个是 基本数据类型,所以使用 class01.isPrimitive() 和 class02.isPrimitive() 判断,然后把基本数据类型的 class 通过 ClassUtils 的转换获得其包装类,再进行比较即可。

    ClassUtils 源码内是初始化了一个 Hashmap 给我们提供类型转换,使用 Hash 处理都是 O1 的时间复杂度,所以使用的话会省事快捷

    假设我默认值都是返回 0  '0'  0.0:

    import org.apache.commons.lang.ClassUtils;
    
    public class PrimitiveTest {
    
        /**
         * 返回一个默认数据类型的 基本数据类型 封装类
         */
        public Object getPrimitiveInstance(Class returnType) throws Exception {
            Object res = null;
            if(returnType == null || returnType == void.class) {
                return res;
            }
            else if(returnType.isPrimitive() || ClassUtils.wrapperToPrimitive(returnType) != null) {
                Class wrapper = ClassUtils.primitiveToWrapper(returnType);
                if(wrapper == Character.class)
                    res = '0';
                else
                    res = wrapper.getConstructor(String.class).newInstance("0");
            }
            return res;
        }
    
        /**
         * 判断基本数据类型是否相等,一般class和,包装类和基本数据类型比较
         */
        public boolean compareParimitiveWithWrapper(Class clazz01, Class clazz02) throws Exception {
            if(clazz01 == clazz02) return true;
            else if(clazz01.isPrimitive()) return clazz02 == ClassUtils.primitiveToWrapper(clazz01);
            else if(clazz02.isPrimitive()) return clazz01 == ClassUtils.primitiveToWrapper(clazz02);
            return false;
        }
    
        // 用于测试
        public static void main(String[] args) throws Throwable {
            PrimitiveTest t = new PrimitiveTest();
    
            // ======== getPrimitiveInstance ========
            System.out.println("======== getPrimitiveInstance ========");
            // 基本数据类型
            System.out.println(t.getPrimitiveInstance(Byte.class));
            System.out.println(t.getPrimitiveInstance(byte.class));
            System.out.println(t.getPrimitiveInstance(Short.class));
            System.out.println(t.getPrimitiveInstance(short.class));
            System.out.println(t.getPrimitiveInstance(Integer.class));
            System.out.println(t.getPrimitiveInstance(int.class));
            System.out.println(t.getPrimitiveInstance(Long.class));
            System.out.println(t.getPrimitiveInstance(long.class));
            System.out.println(t.getPrimitiveInstance(Float.class));
            System.out.println(t.getPrimitiveInstance(float.class));
            System.out.println(t.getPrimitiveInstance(Double.class));
            System.out.println(t.getPrimitiveInstance(double.class));
            System.out.println(t.getPrimitiveInstance(Boolean.class));
            System.out.println(t.getPrimitiveInstance(boolean.class));
            System.out.println(t.getPrimitiveInstance(Character.class));
            System.out.println(t.getPrimitiveInstance(char.class));
    
            // 其他类型
            System.out.println("=== 其他数据类型 ===");
            System.out.println(t.getPrimitiveInstance(String.class));
            System.out.println(t.getPrimitiveInstance(Void.class));
            System.out.println(t.getPrimitiveInstance(void.class));
            System.out.println(t.getPrimitiveInstance(PrimitiveTest.class));
    
            // ======== compareParimitiveWithWrapper ========
            // 不提供 null 判断
            System.out.println("======== compareParimitiveWithWrapper ========");
            System.out.println(t.compareParimitiveWithWrapper(Integer.class, int.class));
            System.out.println(t.compareParimitiveWithWrapper(Integer.class, boolean.class));
            System.out.println(t.compareParimitiveWithWrapper(int.class, int.class));
            System.out.println(t.compareParimitiveWithWrapper(Integer.class, Integer.class));
            System.out.println(t.compareParimitiveWithWrapper(PrimitiveTest.class, int.class));
            System.out.println(t.compareParimitiveWithWrapper(PrimitiveTest.class, Integer.class));
            System.out.println(t.compareParimitiveWithWrapper(PrimitiveTest.class, PrimitiveTest.class));
            System.out.println(t.compareParimitiveWithWrapper(Void.class, void.class));
        }
    
    }
    

     

    展开全文
  • 使用Java包装类和基本类型做比较的时候发现了包装本身存在的坑,参考的JDK版本是1.8.0_121,下面是例子代码:  Short packShort=1; short baseShort=1; Integer packInt=1; int baseInt=1; //用Short的equals()...

    使用Java的包装类和基本类型做比较的时候发现了包装本身存在的坑,参考的JDK版本是1.8.0_121,下面是例子代码: 

    Short packShort=1;
    short baseShort=1;
    Integer packInt=1;
    int baseInt=1;
    //用Short的equals()方法与short进行比较
    System.out.println(packShort.equals(baseShort));
    //用==比较Short和short
    System.out.println(packShort==baseShort);
    //用Short的equals()方法与int进行比较
    System.out.println(packShort.equals(baseInt));
    //用Short的equals()方法与Integer进行比较
    System.out.println(packShort.equals(packInt));
    //用==比较Short和int
    System.out.println(packShort==baseInt);
    //用==比较Short和Integer,不能进行比较,类型不同
    //System.out.println(packShort==packInt);

    代码的运行结果如下:

    true
    true
    false
    false
    true

    先不分析运行结果,大家可以先看一下Short中的equals()源码: 

    public boolean equals(Object obj) {
        if (obj instanceof Short) {
            return value == ((Short)obj).shortValue();
        }
        return false;
    }

     

    在Integer中equals()代码类似,有兴趣可以自行去看一下,这里就不重复了。以下是结果分析:

    1. 用Short的equals()方法与short进行比较的时候,short类型会被判断为是Short类型的实例,然后两个对象都会被转化为基本类型用==进行比较,所以结果为true。
    2. 用==比较Short和short的时候,Short类型对象被拆箱(转为short基本类型),所以结果为true。
    3. 用Short的equals()方法与int进行比较的时候,由于类型判断那里就已经为false了,直接返回false。
    4. 用Short的equals()方法与Integer进行比较的时候,与用Short的equals()方法与int进行比较的时候同样的原因,返回结果为false。
    5. 用==比较Short和int的时候,Short首先是进行了拆箱(转为short基本类型),然后是自动提升类型(转为int),之后才进行比较,所以结果为true。

     

    展开全文
  • java数据类型包括两大基本数据类型引用数据类型。 引用数据类型:、接口、数组。 基本数据类型:数值型{(整数类型:byte、short、int、long)(浮点类型:float、double)}、字符型(char)、布尔型...
  • public class BTest {public static void main(String[] args) {int idcard = 110000000;//基本数据类型Long idCardO = new Long(110000000);...//基本数据类型和包装类型比较Long idCardO2 =ne...
  • 参考博客 案例1: int a = 10; Integer it1 = new Integer(10);...当Integer与int进行==比较时,Integer就会拆箱成一个int类型,所以还是相当于两个int类型进行比较,这里的Integer,不管是直接赋值,还是new创建的对
  • 在初学Java时我们接触到的都是一些基本的数据类型,比如int , float,double等。但是对于高等语言JAVA等面向对象的语言来说,一切都是对象。...二者之间的关系:(1)包装类和基本数据类型相对应。除...
  • 在初学Java时我们接触到的都是一些基本的数据类型,比如int , float,double等。但是对于高等语言JAVA等面向对象的语言来说,一切都是对象。...基于此,这些基础数据类型的包装类就产生了。 二者之间的关系: (...
  • Java基本类型和包装类的各类比较(==),以及包装类的对象缓存池 Java中的基本类型及其包装类比较(==)一直是一个比较头疼的问题,不仅有自动装箱拆箱操作,部分的包装类还有对象缓存池,这就导致了这部分知识...
  • Java基本数据类和包装类型之间的比较 Java的数据类型分为两种:基本数据类型、引用数据类型 基本数据类型(8种) 整数类型 byte short int long 浮点数类型 float double 字符类型 char 浮点数类型 boolean 引用...
  • 1.Integer类型的对象保存在堆中,引用保存...2.用==比较 Integer i1=1; Integer i2=1; Integer i11=128; Integer i22=128; Integer i3=new Integer(1); Integer i4=new Integer(1); int i5=1; int i6=1; /...
  • 2.== ,在包装类和基本类型使用== 比较的时候,包装类会自动拆装为基本类型再比较 3.小于等于<=127 的boolean,byte,char,和介于-128~127之间的short 和int 被包装到固定地址的包装类对象中.但如果是new 出来的包装...
  • // 一:基本数据类型转成字符串:通过包装类的toString方法 int t1 = 2; String s = Integer.toString(t1); System.out.println(s); // 二:字符串转换成基本数据类型 // 第一种:通过包装类的...
  • Java中的基本类型及其包装类比较(==)一直是一个比较头疼的问题,不仅有自动装箱拆箱操作,部分的包装类还有对象缓存池,这就导致了这部分知识容易混淆。 对于==操作符来说,如果比较的数据是基本类型,则比较...
  • Java 基本数据类型和包装类1 Java 基本数据类型1.1 八种基本数据类型1.2 基本用法及说明byte:short:int:long:float:double:boolean:char:1.3 八种包装类型1.3.1 包装类1.3.2 包装类的构造方法2 int ...
  • public class BoxingTest { @Test public void test1(){ String a = new String("1"); String b = new String("1"); Long c = 1L; System.out.println(...
  • 基本数据类型比包装类性能比较 我们先来看看基本数据类型和包装类在内存中的存储位置 Java中的基本数据类型是直接存储在堆栈中,能高效读取;包装类是通过引用指向具体实例,实例存储在堆(heap)中,指向实例的引用...
  • 比较值是否相等的时候,基本类型用“==” ,String用equals方法,那么基本类型的包装类是不是用这两种都行呢?如下看结果 怎么结果不一致,100等于可以,1000就不可以了?直接看书上的解释吧,如下: ...
  • java包装类

    2020-05-02 23:16:30
    在运算时java会自动把基本数据类型和包装类相互转换 自动装箱:将基本数据类型转换成包装类 自动拆箱:将包装类转换成基本数据类型 特别:Integer的值是在-128到127之间的数时 valueOf直接取缓存里的对象。所以比较 ...
  • Java是一门面向对象的编程语言但家族却存在几个异类,它们不能像对象...包装类的常用方法课程简介Java中数据类型分为基本数据类型引用数据类型基本数据类型没有属性,方法,无法对象化交互。包装类的产生就是为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 614
精华内容 245
关键字:

java包装类和基本类比较

java 订阅