欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

考研二战失败我的从零开始Java入门学习(三)

时间:2023-04-26
文章目录

一、Java数组定义与C++数组定义区别二、内存分配三、形参实参四、String、StringBuffer和StringBulider五、重写和重载


一、Java数组定义与C++数组定义区别

之前用 C++ 的时候都是直接写type Arr[x]或type *Arr = new type[x]

而 Java 有两种不同的写法:

type[] arr 定义了type类型的数组,名称为arr
type arr[] (非首选) 定义了type类型的变量,变量名为arr数组


其中动态初始化和静态初始化分别为:
动态初始化: type[] arr = new type[x];
静态初始化: type[] arr ={…};

二、内存分配

看到教程又联想起408的知识点了,就详细写一下好了:

以C语言为例:C语言编写程序时一般分三个段,它们一般是正文段(即代码和赋值数据段)、数据堆段和数据栈段。二进制代码和常量放在正文段,动态分配存储区在数据堆段,临时使用的变量在数据栈段,而进程的优先级存储在PCB内。

这段内容我是用“堆存栈临”的口诀记住的。

而在Java中,数组的内存分配也类似于上述情况:
1、堆:存放new(对象)。
2、栈:存放局部变量。
3、数据段:存放类变量、常量。
4、代码段:存放方法的定义。


而多个数组的情况下,若定义两数组相同,则指向相同:

而数组在内存中是否连续这个问题,引用自参考资料:
https://blog.csdn.net/MC_007/article/details/106411034

用栈声明的时候很明显,都是连续的。
在堆上的时候,由于是分批次分配内存(首先new出或malloc多少行,然后每一行再分别new),因此其存放是平行的几条连续存储,每一行是连续的,行与行之间并不连续。


三、形参实参

节选自:https://blog.csdn.net/weixin_42738587/article/details/89100872

形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量。
实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值。

public class Test { public static int add(int a,int b){//a和b为形参 return a+b; } public static void main(String[] args) { int A = 1,B = 2; System.out.println(add(A,B));//A和B为实参 }}


四、String、StringBuffer和StringBulider

这里引用自菜鸟教程和https://www.cnblogs.com/weibanggang/p/9455926.html

首先记一下String的简单操作:

连接字符串:

1.string1.concat(string2);

2.“webstie:”.concat(“Runoob”);

3.“Hello,” + " runoob" + “!”

三者共同之处:都是final类,不允许被继承,主要是从性能和安全性上考虑的,因为这几个类都是经常被使用着,且考虑到防止其中的参数被参数修改影响到其他的应用。

StringBuffer是线程安全,可以不需要额外的同步用于多线程中;

StringBuilder是非同步,运行于多线程中就需要使用着单独同步处理,但是速度就比StringBuffer快多了;

StringBuffer与StringBuilder两者共同之处:可以通过append、indert进行字符串的操作。

String实现了三个接口:Serializable、Comparable、CarSequence

StringBuilder只实现了两个接口Serializable、CharSequence,相比之下String的实例可以通过compareTo方法进行比较,其他两个不可以。

public class RunoobTest{ public static void main(String args[]){ StringBuilder sb = new StringBuilder(10); //数组长度为10的String sb.append("Runoob.."); //添加 System.out.println(sb); sb.append("!"); System.out.println(sb); sb.insert(8, "Java");//在第8位加入Java,数组总长度同时改变 System.out.println(sb); sb.delete(5,8);//删除第5位到第8位 数组总长度不变 sb.replace(int start, int end, String str) //替换 System.out.println(sb); }}

运行速度方面:StringBuilder > StringBuffer > String

原因:String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。

线程安全方面:StringBuilder是线程不安全的,而StringBuffer是线程安全的

如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized(同步)关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

总结:
  String:适用于少量的字符串操作的情况

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

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


五、重写和重载

先简述一下重写与重载的区别:

重写(Overriding): 父类与子类之间的多态性,对父类的函数进行重新定义

重载(Overloading): 统一的方式处理不同类型数据的一种手段,在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

//重构class Animal{ public void move(){ System.out.println("动物可以移动"); }} class Dog extends Animal{ public void move(){ System.out.println("狗可以跑和走"); }} public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); // Animal 对象 Animal b = new Dog(); // Dog 对象 a.move();// 执行 Animal 类的方法 b.move();//执行 Dog 类的方法 }}//重载public class Overloading { public int test(){ System.out.println("test1"); return 1; } public void test(int a){ System.out.println("test2"); } //以下两个参数类型顺序不同 public String test(int a,String s){ System.out.println("test3"); return "returntest3"; } public String test(String s,int a){ System.out.println("test4"); return "returntest4"; } public static void main(String[] args){ Overloading o = new Overloading(); System.out.println(o.test()); o.test(1); System.out.println(o.test(1,"test3")); System.out.println(o.test("test4",1)); }}

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。