Java基础知识文档

Java基本程序设计结构编程入门(上)

2020-12-09  本文已影响0人  狐狸等在荒芜沙丘

Java是强类型的语言,学习Java,首先要学习这门程序设计语言的基础概念在程序中的实现方式.

一、数据类型:

在Java中一共有八种基础数据类型,四种整型,两种浮点型,一种表示Unicode编码的字符char类型,还有一种是表示真值的Boolean类型

double类型表示的数值精度是float类型表示数值精度的两倍,double也称为双精度数值,在实际应用中,大多数情况都是使用double,float可以在存储单精度的时候使用.

数据类型的级别从高到低为:byte,short,char(三个平级) -> int ->float -> long -> double
类型之间的转换:从低级别到高级别由系统自动转换,把高级别赋值给低级别的变量时,强制转换

每个基本数据类型都有相应的包装类型,int -> Integer ,double-> Double,float -> Float,short-> Short, long -> Long,boolean -> Boolean,char -> Character,byte -> Byte.基本数据类型和他们各自的包装类之间会有拆箱和装箱的操作,把int类型变量转换为Integer类型叫做装箱,反之则为拆箱.装箱操作都为valueOf()方法,而拆箱基本都是基本数据类型加上Value作为拆箱方法,例如intValue,longValue等等.

二、变量和常量:

三、运算符:

四、字符串:

在实际开发中,几乎没有一个项目不使用String字符串,String字符串用双引号" "进行定义,也可以使用+号对两个字符串进行连接.
String之所以可以存储字符串主要原因是其中定义了一个数组,字符串中每个字符都是保存在数组中.在jdk1.9之前String保存的是字符数组,从jdk1.9开始,String保存的是字节数组.
1.9前源码:

private final char value[];

1.9开始源码:

private final byte[] value;
        String str = "abc";
        String str1 = new String("abc");
        System.out.println(str == str1);

运行结果:false
实际上两个相等的值比较出来却是false,原因就在于==,==比较的是两个数值是否相等,而对于两个对象则比较的是两个对象的内存地址是否相等,很显然,str和str1的内存地址是不相等.我们想要的是内容相等就返回true,在这里就需要用equals,equals比较的是两个对象的内容是否相等.把上面程序==改为equals.

        String str = "abc";
        String str1 = new String("abc");
        System.out.println(str.equals(str1));

运行结果:true

     //直接赋值
      String str =  "aaa"; 
      //new关键字赋值
      String str1 = new String("aaa");

区别:
第一种实例化是直接在堆内存中开辟一块内存存放aaa,在上面已经说明,字符串常量是String的匿名对象,所以str对象则在栈内存中指向这块堆内存.只会产生一个实例化对象,会自动保存到对象池,可以实现字符串对象的重用.
第二种方式是先在堆内存中开辟内存存放aaa,在new的过程中在不同的堆内存地址开辟空间并存放aaa,在栈内存中的str1指向的是后面开辟的堆内存空间,产生两个实例化对象,不会自动保存到对象池,不可以重用.

    //直接赋值
     String str =  "aaa";
     //new关键字赋值
     String str1 = new String("aaa");
     //结果为false
     System.out.println(str == str1);

所以,str == str1的结果为false,==比较的是两个对象的内存地址或者是数值
接下来定义一个新的对象str2,str == str2结果为true.这里结果为true,具体的原因在直接赋值的过程中,涉及到了共享设计的概念,在jvm中有对象池,当创建对象时,会将当前对象的匿名对象入池保存,当以同种方式再次创建对象,会先从池中查找是否存在与当前对象匿名对象内容相等的对象,若已经存在,则不会开辟新的空间,而是直接指向已有的地址.所以结果为true

      //直接赋值
      String str =  "aaa";
      //new关键字赋值
      String str1 = new String("aaa");
      //结果为false
      System.out.println(str == str1);
      String str2 = "aaa";
      //结果为true
      System.out.println(str == str2);

使用构造方法来实例化对象不会在对象池中保存,如果想要入池可以调用intern()方法.如下:

     //直接赋值
     String str = "aaa";
     //new关键字赋值
     String str1 = new String("aaa");
     //结果为false
     System.out.println(str == str1);
     String str2 = "aaa";
     //结果为true
     System.out.println(str == str2);
     String str3 = new String("aaa").intern();
     //结果为true
     System.out.println(str == str3);

以上的结果表明,如果是常量相加,JVM会进行优化,直接编译成结果,如果是变量加常量,会new一个StringBuilder对象append,最后通过StringBuilder的toString方法生成一个新的字符串对象.所以str3与str2的地址不相同.还有一个原因就是静态常量池和运行时常量池的区别,由于str4的"ab","c"都是常量数据,所以在加载的时候会自动处理相应的连接,处理好的连接刚好在静态常量池中存在,str4直接指向的对象的地址也就和str2是同一个地址,而str3中str1是一个变量,程序在加载的时候并不确定str1的内容,因为在字符串连接的时候str1采用的是变量,变量是可以被修改的,所以它不认为最终的str3结果就是需要的结果,str3存储在运行时常量池中.

上一篇 下一篇

猜你喜欢

热点阅读