• Java基础知识


    Java基础知识

    ffer:适用于多线程下在字符缓冲区进行大量操作的情况。

    5.2示例

    以拼接10000次字符串为例,我们看下三者各自需要的时间:

    String str = "";
    long startTime = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
        str = str + i;
    }
    long endTime = System.currentTimeMillis();
    long time = endTime - startTime;
    System.out.println("String消耗时间:" + time);
    
    StringBuilder builder = new StringBuilder("");
    startTime = System.currentTimeMillis();
    for (int j = 0; j < 10000; j++) {
        builder.append(j);
    }
    endTime = System.currentTimeMillis();
    time = endTime - startTime;
    System.out.println("StringBuilder消耗时间:" + time);
    
    StringBuffer buffer = new StringBuffer("");
    startTime = System.currentTimeMillis();
    for (int k = 0; k < 10000; k++) {
        buffer.append(k);
    }
    endTime = System.currentTimeMillis();
    time = endTime - startTime;
    System.out.println("StringBuffer消耗时间:" + time);

    运行结果:

    String消耗时间:258
    StringBuilder消耗时间:0
    StringBuffer消耗时间:1

    也验证了上面所说的StringBuilder > StringBuffer > String。

    6.装箱和拆箱

    6.1什么是装箱?什么是拆箱?

    装箱:自动将基本数据类型转换为包装器类型。

    拆箱:自动将包装器类型转换为基本数据类型。

    Integer i = 10; // 装箱
    int j = i; // 拆箱

    6.2 装箱和拆箱是如何实现的?

    装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器实例的 xxxValue方法实现的。(xxx代表对应的基本数据类型)。

    怎么证明这个结论呢,我们新建个类Main,在主方法中添加如下代码:

    package com.zwwhnly.springbootdemo;
    
    public class Main {
        public static void main(String[] args) {
            Integer i = 100;        
            int j = i;
        }
    }

    然后打开cmd窗口,切换到Main类所在路径,执行命令:javac Main.java,会发现该目录会生成一个Main.class文件,用IDEA打开,会发现编译后的代码如下:

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package com.zwwhnly.springbootdemo;
    
    public class Main {
        public Main() {
        }
    
        public static void main(String[] var0) {
            Integer var1 = Integer.valueOf(100);
            int var2 = var1.intValue();
        }
    }

    6.3示例

    示例1:

    Double i1 = 100.0;
    Double i2 = 100.0;
    Double i3 = 200.0;
    Double i4 = 200.0;
    
    System.out.println(i1==i2);
    System.out.println(i3==i4);

    输出结果:

    false

    false

    为什么都返回false呢,我们看下Double.valueOf()方法,就知晓了:

    private final double value;
    
    public Double(double value) {
       this.value = value;
    }
    
    public static Double valueOf(double d) {
       return new Double(d);
    }

    示例2:

    Boolean i1 = false;
    Boolean i2 = false;
    Boolean i3 = true;
    Boolean i4 = true;
    
    System.out.println(i1==i2);
    System.out.println(i3==i4);

    输出结果:

    true

    true

    为什么都返回true呢,我们看下Boolean.valueOf()方法,就知晓了:

    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false);
    
    public static Boolean valueOf(boolean b) {
       return (b ? TRUE : FALSE);
    }

    7.Java中的值传递和引用传递

    7.1基本概念

    值传递:传递对象的一个副本,即使副本被改变,也不会影响源对象,因为值传递的时候,实际上是将实参的值复制一份给形参。

    引用传递:传递的并不是实际的对象,而是对象的引用,外部对引用对象的改变也会反映到源对象上,因为引用传递的时候,实际上是将实参的地址值复制一份给形参。

    说明:对象传递(数组、类、接口)是引用传递,原始类型数据(整形、浮点型、字符型、布尔型)传递是值传递。

    7.2示例

    示例1(值传递):

    package com.zwwhnly.springbootdemo;
    
    public class ArrayListDemo {
    
        public static void main(String[] args) {
            int num1 = 10;
            int num2 = 20;
    
            swap(num1, num2);
    
            System.out.println("num1 = " + num1);
            System.out.println("num2 = " + num2);
        }
    
        public static void swap(int a, int b) {
            int temp = a;
            a = b;
            b = temp;
    
            System.out.println("a = " + a);
            System.out.println("b = " + b);
        }
    }

    运行结果:

    a = 20

    b = 10

    num1 = 10

    num2 = 20

    虽然在swap()方法中a,b的值做了交换,但是主方法中num1,num2的值并未改变。

    示例2(引用类型传递):

    package com.zwwhnly.springbootdemo; 
    
    public class ArrayListDemo {
    
        public static void main(String[] args) {
            int[] arr = {1, 2, 3, 4, 5};
    
            change(arr);
    
            System.out.println(arr[0]);
        }
    
        public static void change(int[] array) {
            System.out.println(array[0]);
            array[0] = 0;
        }
    }

    运行结果:

    1

    0

    在change()方法中将数组的第一个元素改为0,主方法中数组的第一个元素也跟着变为0。

    示例3(StringBuffer类型):

    package com.zwwhnly.springbootdemo;
    
    public class ArrayListDemo {
    
        public static void main(String[] args) {
            StringBuffer stringBuffer = new StringBuffer("博客园:周伟伟的博客");
            System.out.println(stringBuffer);
    
            changeStringBuffer(stringBuffer);
            System.out.println(stringBuffer);
        }
    
        public static void changeStringBuffer(StringBuffer stringBuffer) {
            stringBuffer = new StringBuffer("掘金:周伟伟的博客");
    
            stringBuffer.append(",欢迎大家关注");
        }
    }

    运行结果:

    博客园:周伟伟的博客

    博客园:周伟伟的博客

    也许你会认为第2次应该输出“掘金:周伟伟的博客,欢迎大家关注”,怎么输出的还是原来的值呢,那是因为在changeStringBuffer中,又new了一个StringBuffer对象,此时stringBuffer对象指向的内存地址已经改变,所以主方法中的stringBuffer变量未受到影响。

    如果修改changeStringBuffer()方法的代码为:

    public static void changeStringBuffer(StringBuffer stringBuffer) {
    
        stringBuffer.append(",欢迎大家关注");
    }

    则运行结果变为了:

    博客园:周伟伟的博客

    博客园:周伟伟的博客,欢迎大家关注

    示例4(String类型):

    package com.zwwhnly.springbootdemo;
    
    public class ArrayListDemo {
    
        public static void main(String[] args) {
            String str = new String("博客园:周伟伟的博客");
            System.out.println(str);
    
            changeString(str);
            System.out.println(str);
        }
    
        public static void changeString(String string) {
            //string = "掘金:周伟伟的博客";
            string = new String("掘金:周伟伟的博客");
        }
    }

    运行结果:

    博客园:周伟伟的博客

    博客园:周伟伟的博客

    在changeString()方法中不管用string = "掘金:周伟伟的博客";还是string = new String("掘金:周伟伟的博客");,主方法中的str变量都不会受影响,也验证了String创建之后是不可变更的。

    示例5(自定义类型):

    package com.zwwhnly.springbootdemo;
    
    public class Person {
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Person(String name) {
            this.name = name;
        }
    }
    package com.zwwhnly.springbootdemo;
    
    public class ArrayListDemo {
    
        public static void main(String[] args) {
            Person person = new Person("zhangsan");
            System.out.println(person.getName());
    
            changePerson(person);
            System.out.println(person.getName());
        }
    
        public static void changePerson(Person p) {
            Person person = new Person("lisi");
            p = person;
        }
    }

    运行结果:

    zhangsan

    zhangsan

    修改changePerson()方法代码为:

    public static void changePerson(Person p) {
        p.setName("lisi");
    }

    则运行结果为:

    zhangsan

    lisi

    8.参考链接

    关于==和equals的区别和联系,面试这么回答就可以

    Java中==号与equals()方法的区别

    Java中的String,StringBuilder,StringBuffer三者的区别

    深入剖析Java中的装箱和拆箱

    Integer、new Integer() 和 int 比较的面试题

    java面试题之int和Integer的区别

    最最最常见的Java面试题总结-第一周

  • 相关阅读:
    两个类重复属性值复制
    IIS请求筛选模块被配置为拒绝超过请求内容长度的请求
    System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本问题
    Oracle 查询表中字段里数据是否有重复
    JS 中如何将<br/> 替换成 /n
    JS 验证数组中是否包含重复元素
    [C#] 使用NPOI将Datatable保存到Excel
    [C#] 将 List 转 DataTable
    [C#] 图文解说调用WebServer实例
    bzoj 3489: A simple rmq problem
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/10988547.html
Copyright © 2020-2023  润新知