栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

2021-10-13

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021-10-13

Java基础知识(一) 1. JVM、JRE和JDK的关系
  1. JDK(Java Development Kit)是针对Java开发人员的产品,是整个Java的核心,包括了Java运行环境、Java工具和Java基础类库,它能够创建和编译程序。
  2. JRE是Java运行时环境。它是运行已编译Java程序所需的所有内容的集合,包括Java虚拟机(JVM),Java类库,Java命令和其他一些基础构件。
  3. JVM就是java虚拟机,它是java实现跨平台最核心的部分,能够运行以Java语言写作的软件程序。JVM 有针对不同系统的特定实现(Windows,Linux,macOS),⽬的是使⽤相同的字节码,它们都会给出相同的结果。
  4. JDK包含JRE,JRE包含JVM,如果你只是为了运⾏⼀下 Java 程序的话,那么你只需要安装 JRE 就可以了。如果你需要进⾏⼀ 些 Java 编程⽅⾯的⼯作,那么你就需要安装 JDK 了。但是,这不是绝对的。有时,即使您不打 算在计算机上进⾏任何 Java 开发,仍然需要安装 JDK。例如,如果要使⽤ JSP 部署 Web 应⽤ 程序,那么从技术上讲,您只是在应⽤程序服务器中运⾏ Java 程序。那你为什么需要 JDK 呢? 因为应⽤程序服务器会将 JSP 转换为 Java servlet,并且需要使⽤ JDK 来编译 servlet。
2. Java语言的特点
  1. 面向对象(封装、继承、多态)
  2. 平台无关性(Java使用虚拟机实现平台无关性)
  3. 可靠性
  4. 安全性
  5. 支持多线程(C++语言没有内置的多线程机制,因此就必须调用操作系统的多线程功能来进行多线程程序设计,而Java语言提供了多线程支持)
  6. 支持网络编程并且很方便
3.Java和C++的区别
  1. Java依靠虚拟机从而实现跨平台性,但是C++依赖于特定的平台
  2. Java没有指针,它的引用可以理解为安全指针,而C++具有和C一样的指针
  3. Java支持垃圾自动回收,而C++需要手动回收
  4. Java不支持多继承,通过实现多个接口来达到相同的目的,而C++支持多继承
  5. java不支持操作符重载,虽然可以对两个String对象执行加法,但是这是语言内置支持的操作,不属于操作符重载,而C++可以
4. Java和Python的区别
  1. Java必须显式声明变量名,而动态类型的Python不需要声明变量。
  2. Python虚拟机没有Java强,Java虚拟机是Java的核心,Python的核心是可以很方便地使用c语言函数或c++库。
  3. Java是一种静态类型语言,Python是一种动态类型语言。
  4. Python是全动态性的,可以在运行时自己修改自己的代码,Java只能通过变通方法实现。
5. Java基本数据类型
类型关键字包装器类型占用字节取值范围默认值
字节型byteByte1-128 ~ 1270
短整形shortShort2-2 ^ 15 ~ 2 ^ 15-1(32768-1)0
整形intInteger4-2^ 31~2^31 - 10
长整形longLong8-2^ 63 ~ 2^ 63 - 10L
单精度浮点型floatFloat43.4e-45 ~ 1.4e380.0F
双精度浮点型doubleDouble80.0D
字符型charCharacter2
布尔型booleanBoolean1true/falsefalse
6. 类型转换
  1. 隐式类型转换:从存储范围小的类型到存储范围大的类型. byte->short(char)->int->long->float->double
  2. 显示类型转换:从存储范围大的类型到存储范围小的类型。double->float->long->int->short(char)->byte,这样转换可能会发生精度下降问题。
  3. 案例
short s = 1;
s = s + 1;

像上面这样写就会出现错误,因为1是int类型,s+1会自动转换为int类型,将int类型赋值给short类型会报错,可以采用下面的写法

short s = 1;
s = (short)(s+1)
// 或者是
short s = 1;
s += 1; // s+=1 会自动进行强制类型转换
7. 自动装箱与拆箱(原理也要知道)
  1. 装箱:将基本类型用包装类型包装起来
  2. 拆箱:将包装器类型转化为基本类型
  3. 问题: int 和Integer的区别? 底层如何实现? 使用包装类型会存在什么样的问题
  4. 案例分析
public class Main {
   public static void main(String[] args) {
   
           Integer a = 100;
           Integer b = 100;
           Integer c = 128;
           Integer d = 128;
​
           System.out.println(a==b); // true
           System.out.println(c==d); // false
   }
}

很多人看到这个结果会疑惑,为什么会是一个true,一个false,其实从源码中可以找到原因,首先找到Integer中的valueOf方法

public static Integer valueOf(int i) {
      if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
      return new Integer(i);
}
private static class IntegerCache {
          static final int low = -128;
          static final int high; // 127
          static final Integer cache[];
  
          static {
              // high value may be configured by property
              int h = 127;
              String integerCacheHighPropValue =
                  sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
              if (integerCacheHighPropValue != null) {
                  try {
                      int i = parseInt(integerCacheHighPropValue);
                      i = Math.max(i, 127);
                      // Maximum array size is Integer.MAX_VALUE
                      h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                  } catch( NumberFormatException nfe) {
                      // If the property cannot be parsed into an int, ignore it.
                  }
              }
              high = h;
             cache = new Integer[(high - low) + 1];
              int j = low;
              for(int k = 0; k < cache.length; k++)
                  cache[k] = new Integer(j++);
  
              // range [-128, 127] must be interned (JLS7 5.1.7)
              assert IntegerCache.high >= 127;
          }
  
          private IntegerCache() {}
      }

Integer类中有一个缓存机制,当我们执行 Integer i = 40 时,会首先i是不是在-128到127之间,如果在的话就会取出缓存中的对象,如果不在的话,就会创建一个新的对象。
Integer、Short、Byte、Character、Long这几个类的实现原理都相似
Double和Float的实现原理与之不同,每次都会新创建一个对象,代码如下所示
Boolean是单独的实现方式

// Double的valueOf源码,float 的与其相似
public static Double valueOf(double d) {
         return new Double(d);
}

// Boolean的实现方法
public static Boolean valueOf(boolean b) {
       return (b ? TRUE : FALSE);
   }
  1. 案例分析二
public class Main {
    public static void main(String[] args) {
        Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Long g = 3L;
        int int1 = 12;
        int int2 = 12;
        Integer integer1 = new Integer(12);
        Integer integer2 = new Integer(12);
        Integer integer3 = new Integer(1);

        System.out.println("c==(a+b) ->"+ (c==(a+b)));  // true
        System.out.println("g==(a+b) ->" + (g==(a+b))); // true
        System.out.println( "c.equals(a+b) ->" + (c.equals(a+b))); // true
        System.out.println( "g.equals(a+b) ->" + (g.equals(a+b))); // false
        System.out.println("int1 == int2 -> " + (int1 == int2)); // true
        System.out.println("int1 == integer1 -> " + (int1 == integer1)); // true
        System.out.println("integer1 == integer2 -> " + (integer1 == integer2)); // false
        System.out.println("integer3 == a1 -> " + (integer3 == a)); // false
    }
}

解释
1.当 "=="运算符的两个操作数都是包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。所以c==a+b,g==a+b为true。

2.而对于equals方法会先触发自动拆箱过程,再触发自动装箱过程。也就是说a+b,会先各自调用intValue方法,得到了加法运算后的数值之后,便调用Integer.valueOf方法,再进行equals比较。所以c.equals(a+b)为true。而对于g.equals(a+b),a+b会先拆箱进行相加运算,在装箱进行equals比较,但是装箱后为Integer,g为Long,所以g.equals(a+b)为false。

3.int1 == int2为true无需解释,int1 == integer1,在进行比较时,integer1会先进行一个拆箱操作变成int型在进行比较,所以int1 == integer1为true。

4.integer1 == integer2->false。integer1和integer2都是通过new关键字创建的,可以看成两个对象,所以integer1 == integer2 为false。integer3 == a1 -> false , integer3是一个对象类型,而a1是一个常量它们存放内存的位置不一样,所以integer3 == a1为false,具体原因可学习下java的内存模型。

8. String(不是基本数据类型)
  1. String的不可变性
    1. 在Java 8中String内部使用char数组存储数据,并且被final修饰,因此不可以被继承
public final class String implements java.io.Serializable, Comparable, CharSequence {   
    private final char value[];
}
  1. String类的常见方法
    1. length():返回字符串长度
    2. charAt():返回指定索引处的字符
    3. substring():截取字符串
    4. trim():去除字符串两端空白
    5. split():分割字符串,返回一个分割后的字符串数组。
    6. replace():字符串替换。
    7. indexOf():返回指定字符的索引。
    8. toLowerCase():将字符串转成小写字母。
    9. toUpperCase():将字符串转成大写字符。
  2. String 和 StringBuilder、StringBuffer的区别是什么?
    1. 可变形:String不可变,StringBuffer和StringBuilder是可变的
    2. 线程安全性:String不可变,所以是线程安全的。StringBuffer对方法加了同步锁,所以也是线程安全的,StringBuilder不是线程安全的
    3. 性能:StringBuilder > StringBuffer > String
  3. 字符串常量池
    1. JDK1.8之后,取消了永久代,使用了元空间,方法区也移动到了元空间,但是字符串常量池还在堆中。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/322457.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号