| \\
| 字符 \
|
| \n
| 换行符 |
| \t
| 制表符 Tab
|
| \r
| 回车符 |
那多个字符串之间或者字符串和其他类型数据之间,该如何进行连接呢?
Java 编译器中,对于字符串和其他数据类型之间,可以使用 +
进行连接,编译器会自动将其他数据类型自动转换为字符串,然后再进行连接;
String
既然是不可变,那有什么优点呢?
- 用于缓存
hash
值
由于 String
的 hash
值被频繁使用,它的不可变性使得 hash
值也不可变,此时只需要进行一次计算;
- 字符串常量池(String Pool)的需要
如果一个 String
对象已经被创建过,那么就会优先从字符串常量池中获取其引用,其不可变性确保了不同引用指向同一 String
对象;
- 安全性
我们经常用 String
作为我们方法的参数,其不变性能够保证参数不可变;
- 线程安全
String
的不可变性让它天生 具备线程安全,能够在多个线程中方便使用而不用考虑线程安全问题。
String、StringBuilder、StringBuffer
对比,该如何选择?
| | 可变性 | 线程安全 | 适用场景 |
| — | — | — | — |
| String
| 不可变 | 安全 | 操作少量的数据 |
| StringBuffer
| 可变 | 安全,内部使用 synchronized
进行同步 | 多线程操作字符串缓冲区下操作大量数据 |
| StringBuilder
| 可变 | 不安全 | 单线程操作字符串缓冲区下操作大量数据,性能高于 StringBuffer
|
通过
new String(“xxx”)
创建字符串的两种情况?
使用 new
的方式创建字符串对象,会有两种不同的情况:
- String Pool 中不存在 “xxx”
此时会创建两个字符串对象,“xxx” 属于字符串字面量,因此在编译期会在 String Pool 中创建一个字符串对象,用于指向该字符串的字面量 “xxx”;然后 new
会在堆中创建一个字符串对象;
- String Pool 中存在 “xxx”
此时只需要创建一个字符串对象,由于 String Pool 中已经存在指向 “xxx” 的对象,所以直接在堆中创建一个字符串对象;
数据类型转换
对于基本数据类型,不同类型之间是可以相互转换的,但是需要满足一定的条件;
从小到大自动转,从大到小强制转。
即就是,对于低精度的数据类型,如果要转换为高精度的数据类型,直接将低精度的值赋给高精度的值即可;
但对于高精度的数据类型,如果想要转换为低精度的数据类型,则需要采用 强制转换 的手段,但此时需要承担精度丢失的风险,就像从一个大杯子往一个小杯子里倒水,你要做好小杯子可能装不下溢出的情况;
int a = 110;
long b = 113;
// 低精度转高精度,由于 long 的范围比 int 大,所以可以自动转
b = a;
// 高精度住哪低精度,由于 long 的范围比 int 大,所以需要强制转
a = (int)b;
隐式转换(自动类型转换)
当满足如下条件时,如果将一种类型的数据赋值给另一种数据类型变量时,将执行自动类型转换:
- 两种数据类型彼此兼容;
- 目标数据类型的取值范围大于源数据类型;
一般而言,隐式转换的规则是从低级类型数据转换为高级类型数据,对应规则如下:
- 数值类型:
byte -> short -> int -> long -> float -> double
- 字符类型转整型:
char -> int
显式转换(强制类型转换)
那既然满足上述两个条件时会发生隐式转换,那不满足同时我们又想进行数据类型转换时,我们该怎么办呢?
这个时候就需要我们的 显式转换 登场了,其语法格式如下:
(type) variableName;
我们举个 🌰 来说下:
int num = 3;
double ans = 5.0;
// 要将 double 类型的值赋值给 int,则需要强制转换
num = (int)ans;
**注意:**强制转换可能会导致精度丢失,所以一般情况下尽量能不用就不用。
常见数据类型转换方法
- 字符串与其他类型之间的转换
- 其他类型 -> 字符串
- 调用类的串转换方法:
X.toString()
;
- 自动转换:
"" + X
;
- 利用
String
的方法:String.valueOf(X)
;
// 方法 1
String str1 = Integer.toString(int num);
String str2 = Long.toString(long num);
String str3 = Float.toString(flaot num);
String str4 = Double.toString(double num);
// 方法 2
String str = “” + num ; // num 是 int、long、float、double 类型
// 方法 3
String str1 = String.valueOf(int num);
String str2 = String.valueOf(long num);
String str3 = String.valueOf(float num);
String str4 = String.valueOf(double num);
- 字符串 - > 其他类型
-
调用
parseXXX
方法,比如parseLong、parseFloat、parseDouble...
; -
先调用
valueOf()
,方法,然后再调用xxxValue()
方法;
// 方法 1
int num1 = Integer.parseInt(String str);
Long num2 = Long.parseLong(String str);
Float num3 = Float.parseFloat(String str);
Double num4 = Double.parseDouble(String str);
// 方法 2
int num1 = Integer.valueOf(String str).intValue();
Long num2 = Long.valueOf(String str).longValue();
Float num1 = Float.valueOf(String str).floatValue();
Double num1 = Double.valueOf(String str).doubleValue();
- int、float、double 之间的转换
float -> double
float num = 1.0f;
Float num1 = new Float(num);
double num2 = num1.doubleValue();
double -> float
double num = 100.0;
float num1 = (float)num;
double -> int
double num = 100.0;
Double num1 = new Double(num);
int num2 = num1.intValue();
int -> double
int num = 200;
double num1 = num;
我们已经学会了如何定义变量,也知道了使用各种数据类型来定义变量。但是还有一点不知道大家有没有注意到,如果我们的定义变量在不同的位置,其作用是不是相同的呢?
这就涉及到变量的作用域,一般根据其作用域的不同,可以分为:
-
成员变量:定义在方法体和语句块外,不属于任何一个方法,能在整个类中起作用;
-
局部变量:定义在方法或方法体中的变量,作用域是其所在的代码块;
成员变量
成员变量又可以分为 全局变量(又叫实例变量) 和 静态变量(也叫类变量),两者的区别如下:
| 名称 | 修饰符 | 访问方式 | 生命周期 |
| — | — | — | — |
| 全局变量 | 无 | 对象名.变量名 | 一旦对象被引用,则实例变量就存在 |
| 静态变量 | static
| 类名.变量名 | 同类共生死,只有当类被 GC 回收时才会被销毁 |
public class Person {
// 成员变量,全局变量
String name;
// 成员变量,全局变量
int age;
// 成员变量,静态变量
public static final String wechatPublic = “公众号:村雨遥”;
// 成员变量,静态变量
public static final String website = “http://cunyu1943.site”;
}
局部变量
成员变量指定义在方法或方法体中的变量,作用域是其所在的代码块,可以分为如下三种:
- 形参
public class Main {
// 方法中的参数
public static void func(int num) {
System.out.println("num = " + num);
}
public static void main(String[] args) {
func(3);
}
}
- 方法内定义
public class Main {
public static void main(String[] args) {
int num = 10;
if (num > 5) {
// 声明一个 int 类型的局部变量
int tmp = 5;
System.out.println("tmp = " + tmp);
System.out.println("num = " + num);
}
System.out.println("num = " + num);
}
}
- 代码块定义
public class Main {
public static void func() {
try {
System.out.println(“Hello!Exception!”);
} catch (Exception e) { // 异常处理块,参数为 Exception 类型
e.printStackTrace();
}
}
public static void main(String[] args) {
func();
}
}
简介
既然有变量,那就有与之相对的常量(也就是值是固定的,不能再变)。
常量又叫做字面常量,是通过数据直接来表示的,在程序运行过程中不能发生改变。通常我们把 Java 中用 final
关键字所修饰的成员变量叫做常量,它的值一旦给定就无法再进行改变!
分类
Java 中使用 final
关键字来声明常量,其语法格式如下:
final 数据类型 常量名 = 常量初始值;
public class Main{
public static void main(String[] args){
// 声明一个常量并赋值
final int num = 1024;
// 再次赋值,将导致编译错误
num = 1943;
// 声明一个常量但不赋值
final int id;
// 因为声明时未赋值,所以可以进程初次赋值
id = 1;
// 常量已经赋值过了,再次赋值将导致编译错误
id = 2;
}
}
常量可以分为如下 3 种类型:
-
静态常量:
final
之前用public staic
修饰,表示该常量的作用域是全局的,我们不用创建对象就能够访问它。 -
成员常量:类似于成员变量,但是最大的不同在于它不能被修改。
-
局部常量:作用类似于局部变量,不同之处也在于不能修改。
public class Main{
// 静态变量
public static final dobule PI = 3.14;
// 成员常量
final int num = 1024;
public static void main(String[] args){
// 局部变量
final long count = 1000;
}
}
PS:final
修饰变量后,该变量则变为常量。而 final
也还可以用来修饰类和方法,修饰方法时,表示这个方法不能被重写(但可以重载);修饰类时,则表明该类无法被继承。这些东西这时候你可能会觉得很陌生,不过等我们后续学习了面向对象之后,你就会发现其实很简单。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/9aec2fd55acb77a2d6047f49815c792a.jpeg)
Spring全套教学资料
Spring是Java程序员的《葵花宝典》,其中提供的各种大招,能简化我们的开发,大大提升开发效率!目前99%的公司使用了Spring,大家可以去各大招聘网站看一下,Spring算是必备技能,所以一定要掌握。
目录:
部分内容:
Spring源码
- 第一部分 Spring 概述
- 第二部分 核心思想
- 第三部分 手写实现 IoC 和 AOP(自定义Spring框架)
- 第四部分 Spring IOC 高级应用
基础特性
高级特性 - 第五部分 Spring IOC源码深度剖析
设计优雅
设计模式
注意:原则、方法和技巧 - 第六部分 Spring AOP 应用
声明事务控制 - 第七部分 Spring AOP源码深度剖析
必要的笔记、必要的图、通俗易懂的语言化解知识难点
脚手框架:SpringBoot技术
它的目标是简化Spring应用和服务的创建、开发与部署,简化了配置文件,使用嵌入式web服务器,含有诸多开箱即用的微服务功能,可以和spring cloud联合部署。
Spring Boot的核心思想是约定大于配置,应用只需要很少的配置即可,简化了应用开发模式。
- SpringBoot入门
- 配置文件
- 日志
- Web开发
- Docker
- SpringBoot与数据访问
- 启动配置原理
- 自定义starter
微服务架构:Spring Cloud Alibaba
同 Spring Cloud 一样,Spring Cloud Alibaba 也是一套微服务解决方案,包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
- 微服务架构介绍
- Spring Cloud Alibaba介绍
- 微服务环境搭建
- 服务治理
- 服务容错
- 服务网关
- 链路追踪
- ZipKin集成及数据持久化
- 消息驱动
- 短信服务
- Nacos Confifig—服务配置
- Seata—分布式事务
- Dubbo—rpc通信
Spring MVC
目录:
部分内容:
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
Alibaba
同 Spring Cloud 一样,Spring Cloud Alibaba 也是一套微服务解决方案,包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
- 微服务架构介绍
- Spring Cloud Alibaba介绍
- 微服务环境搭建
- 服务治理
- 服务容错
- 服务网关
- 链路追踪
- ZipKin集成及数据持久化
- 消息驱动
- 短信服务
- Nacos Confifig—服务配置
- Seata—分布式事务
- Dubbo—rpc通信
[外链图片转存中…(img-yy14Wj7F-1713524469137)]
[外链图片转存中…(img-18Wt3rCy-1713524469138)]
Spring MVC
目录:
[外链图片转存中…(img-bIxOTol4-1713524469140)]
[外链图片转存中…(img-B6uH0uar-1713524469142)]
[外链图片转存中…(img-pXyWoiER-1713524469143)]
部分内容:
[外链图片转存中…(img-IEh5auFb-1713524469145)]
[外链图片转存中…(img-lT0UJc10-1713524469146)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!