【Java 从入坑到放弃】No 3

| \\ | 字符 \ |

| \n | 换行符 |

| \t | 制表符 Tab |

| \r | 回车符 |

那多个字符串之间或者字符串和其他类型数据之间,该如何进行连接呢?

Java 编译器中,对于字符串和其他数据类型之间,可以使用 + 进行连接,编译器会自动将其他数据类型自动转换为字符串,然后再进行连接;

String 既然是不可变,那有什么优点呢?

  1. 用于缓存 hash

由于 Stringhash 值被频繁使用,它的不可变性使得 hash 值也不可变,此时只需要进行一次计算;

  1. 字符串常量池(String Pool)的需要

如果一个 String 对象已经被创建过,那么就会优先从字符串常量池中获取其引用,其不可变性确保了不同引用指向同一 String 对象;

  1. 安全性

我们经常用 String 作为我们方法的参数,其不变性能够保证参数不可变;

  1. 线程安全

String 的不可变性让它天生 具备线程安全,能够在多个线程中方便使用而不用考虑线程安全问题。

String、StringBuilder、StringBuffer 对比,该如何选择?

| | 可变性 | 线程安全 | 适用场景 |

| — | — | — | — |

| String | 不可变 | 安全 | 操作少量的数据 |

| StringBuffer | 可变 | 安全,内部使用 synchronized 进行同步 | 多线程操作字符串缓冲区下操作大量数据 |

| StringBuilder | 可变 | 不安全 | 单线程操作字符串缓冲区下操作大量数据,性能高于 StringBuffer |

通过 new String(“xxx”) 创建字符串的两种情况?

使用 new 的方式创建字符串对象,会有两种不同的情况:

  1. String Pool 中不存在 “xxx”

此时会创建两个字符串对象,“xxx” 属于字符串字面量,因此在编译期会在 String Pool 中创建一个字符串对象,用于指向该字符串的字面量 “xxx”;然后 new 会在堆中创建一个字符串对象;

  1. String Pool 中存在 “xxx”

此时只需要创建一个字符串对象,由于 String Pool 中已经存在指向 “xxx” 的对象,所以直接在堆中创建一个字符串对象;

数据类型转换

对于基本数据类型,不同类型之间是可以相互转换的,但是需要满足一定的条件;

从小到大自动转,从大到小强制转

即就是,对于低精度的数据类型,如果要转换为高精度的数据类型,直接将低精度的值赋给高精度的值即可;

但对于高精度的数据类型,如果想要转换为低精度的数据类型,则需要采用 强制转换 的手段,但此时需要承担精度丢失的风险,就像从一个大杯子往一个小杯子里倒水,你要做好小杯子可能装不下溢出的情况;

int a = 110;

long b = 113;

// 低精度转高精度,由于 long 的范围比 int 大,所以可以自动转

b = a;

// 高精度住哪低精度,由于 long 的范围比 int 大,所以需要强制转

a = (int)b;

隐式转换(自动类型转换)

当满足如下条件时,如果将一种类型的数据赋值给另一种数据类型变量时,将执行自动类型转换:

  1. 两种数据类型彼此兼容;
  1. 目标数据类型的取值范围大于源数据类型;

一般而言,隐式转换的规则是从低级类型数据转换为高级类型数据,对应规则如下:

  • 数值类型byte -> short -> int -> long -> float -> double
  • 字符类型转整型char -> int
显式转换(强制类型转换)

那既然满足上述两个条件时会发生隐式转换,那不满足同时我们又想进行数据类型转换时,我们该怎么办呢?

这个时候就需要我们的 显式转换 登场了,其语法格式如下:

(type) variableName;

我们举个 🌰 来说下:

int num = 3;

double ans = 5.0;

// 要将 double 类型的值赋值给 int,则需要强制转换

num = (int)ans;

**注意:**强制转换可能会导致精度丢失,所以一般情况下尽量能不用就不用。

常见数据类型转换方法
  1. 字符串与其他类型之间的转换
  • 其他类型 -> 字符串
  1. 调用类的串转换方法:X.toString()
  1. 自动转换:"" + X
  1. 利用 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);

  • 字符串 - > 其他类型
  1. 调用 parseXXX 方法,比如 parseLong、parseFloat、parseDouble...

  2. 先调用 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();

  1. 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开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

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)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值