Java学习笔记,笔记内容来源:菜鸟编程、AI 提问的自我总结
Java 基础数据类型
变量就是申请内存来储存值。也就是说,当创建变量的时候,需要在内存中申请空间。
内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据 。
因此,通过定义不同类型的变量,可以在内存中储存整数、小数或字符。
Java 的两大数据类型:
- 内置数据类型 / 基本数据类型
- 引用数据类型
内置数据类型 / 基本数据类型
Java 语言提供了八种剧本类型。
- 六种数字类型(四个整数型,两个浮点型)
- 一种字符类型
- 还有一种布尔型
byte
- byte 数据类型是 8 位、有符号的,以二进制补码表示的整数:
- 最小值
-128(-2^7)
; - 最大值
127(2^7-1)
; - 默认值是
0
- byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;
- 例子:byte a = 100, byte b = -50
short
- short 数据类型是 16 位、有符号的以二进制补码表示的整数
- 最小值是
-32768(-2^15)
; - 最大值是
32767(2^15 - 1)
; - Short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;
- 默认值是 0;
- 例子:short s = 1000,short r = -20000。
int
- int 数据类型是32位、有符号的以二进制补码表示的整数;
- 最小值是
-2,147,483,648(-2^31)
; - 最大值是
2,147,483,647(2^31 - 1)
; - 一般地整型变量默认为 int 类型;
- 默认值是 0 ;
- 例子:int a = 100000, int b = -200000。
long
- long 数据类型是 64 位、有符号的以二进制补码表示的整数;
- 最小值是
-9,223,372,036,854,775,808(-2^63)
; - 最大值是
9,223,372,036,854,775,807(2^63 -1)
; - 这种类型主要使用在需要比较大整数的系统上;
- 默认值是 0L;
- 例子: long a = 100000L,long b = -200000L。
"L"理论上不分大小写,但是若写成"l"容易与数字"1"混淆,不容易分辩。所以最好大写。
float
- float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;
- float 在储存大型浮点数组的时候可节省内存空间;
- 默认值是 0.0f;
- 浮点数不能用来表示精确的值,如货币;
- 例子:float f1 = 234.5f。
double
-
double 数据类型是双精度、64 位、符合 IEEE 754 标准的浮点数;
-
浮点数的默认类型为 double 类型;
-
double类型同样不能表示精确的值,如货币;
-
默认值是 0.0d;
扫描二维码关注公众号,回复: 17476754 查看本文章 -
例子:
double d1 = 7D ; double d2 = 7.; double d3 = 8.0; double d4 = 8.D; double d5 = 12.9867;
7 是一个 int 字面量,而 7D,7. 和 8.0 是 double 字面量。
boolean
- boolean数据类型表示一位的信息;
- 只有两个取值:true 和 false;
- 这种类型只作为一种标志来记录 true/false 情况;
- 默认值是 false;
- 例子:boolean one = true。
char
- char 类型是一个单一的 16 位 Unicode 字符;
- 最小值是 \u0000(十进制等效值为 0);
- 最大值是 \uffff(即为 65535);
- char 数据类型可以储存任何字符;
- 例子:char letter = ‘A’;
实例
对于数值类型的基本类型的取值范围,我们无需强制去记忆,因为它们的值都已经以常量的形式定义在对应的包装类中了。请看下面的例子:
public class PrimitiveTypeTest {
public static void main(String[] args) {
// byte
System.out.println("基本类型:byte 二进制位数:" + Byte.SIZE);
System.out.println("包装类:java.lang.Byte");
System.out.println("最小值:Byte.MIN_VALUE=" + Byte.MIN_VALUE);
System.out.println("最大值:Byte.MAX_VALUE=" + Byte.MAX_VALUE);
System.out.println();
// short
System.out.println("基本类型:short 二进制位数:" + Short.SIZE);
System.out.println("包装类:java.lang.Short");
System.out.println("最小值:Short.MIN_VALUE=" + Short.MIN_VALUE);
System.out.println("最大值:Short.MAX_VALUE=" + Short.MAX_VALUE);
System.out.println();
// int
System.out.println("基本类型:int 二进制位数:" + Integer.SIZE);
System.out.println("包装类:java.lang.Integer");
System.out.println("最小值:Integer.MIN_VALUE=" + Integer.MIN_VALUE);
System.out.println("最大值:Integer.MAX_VALUE=" + Integer.MAX_VALUE);
System.out.println();
// long
System.out.println("基本类型:long 二进制位数:" + Long.SIZE);
System.out.println("包装类:java.lang.Long");
System.out.println("最小值:Long.MIN_VALUE=" + Long.MIN_VALUE);
System.out.println("最大值:Long.MAX_VALUE=" + Long.MAX_VALUE);
System.out.println();
// float
System.out.println("基本类型:float 二进制位数:" + Float.SIZE);
System.out.println("包装类:java.lang.Float");
System.out.println("最小值:Float.MIN_VALUE=" + Float.MIN_VALUE);
System.out.println("最大值:Float.MAX_VALUE=" + Float.MAX_VALUE);
System.out.println();
// double
System.out.println("基本类型:double 二进制位数:" + Double.SIZE);
System.out.println("包装类:java.lang.Double");
System.out.println("最小值:Double.MIN_VALUE=" + Double.MIN_VALUE);
System.out.println("最大值:Double.MAX_VALUE=" + Double.MAX_VALUE);
System.out.println();
// char
System.out.println("基本类型:char 二进制位数:" + Character.SIZE);
System.out.println("包装类:java.lang.Character");
// 以数值形式而不是字符形式将Character.MIN_VALUE输出到控制台
System.out.println("最小值:Character.MIN_VALUE="
+ (int) Character.MIN_VALUE);
// 以数值形式而不是字符形式将Character.MAX_VALUE输出到控制台
System.out.println("最大值:Character.MAX_VALUE="
+ (int) Character.MAX_VALUE);
}
}
编译以上代码输出结果如下所示:
基本类型:byte 二进制位数:8
包装类:java.lang.Byte
最小值:Byte.MIN_VALUE=-128
最大值:Byte.MAX_VALUE=127
基本类型:short 二进制位数:16
包装类:java.lang.Short
最小值:Short.MIN_VALUE=-32768
最大值:Short.MAX_VALUE=32767
基本类型:int 二进制位数:32
包装类:java.lang.Integer
最小值:Integer.MIN_VALUE=-2147483648
最大值:Integer.MAX_VALUE=2147483647
基本类型:long 二进制位数:64
包装类:java.lang.Long
最小值:Long.MIN_VALUE=-9223372036854775808
最大值:Long.MAX_VALUE=9223372036854775807
基本类型:float 二进制位数:32
包装类:java.lang.Float
最小值:Float.MIN_VALUE=1.4E-45
最大值:Float.MAX_VALUE=3.4028235E38
基本类型:double 二进制位数:64
包装类:java.lang.Double
最小值:Double.MIN_VALUE=4.9E-324
最大值:Double.MAX_VALUE=1.7976931348623157E308
基本类型:char 二进制位数:16
包装类:java.lang.Character
最小值:Character.MIN_VALUE=0
最大值:Character.MAX_VALUE=65535
Float和Double的最小值和最大值都是以科学记数法的形式输出的,结尾的"E+数字"表示E之前的数字要乘以10的多少次方。比如3.14E3就是3.14 × 103 =3140,3.14E-3 就是 3.14 x 10-3 =0.00314。
实际上,JAVA中还存在另外一种基本类型 void,它也有对应的包装类 java.lang.Void,不过我们无法直接对它们进行操作。
类型的默认值
下表列出了 Java 各个类型的默认值:
数据类型 | 默认值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
char | ‘u0000’ |
String (or any object) | null |
boolean | false |
实例
public class Test {
static boolean bool;
static byte by;
static char ch;
static double d;
static float f;
static int i;
static long l;
static short sh;
static String str;
public static void main(String[] args) {
System.out.println("Bool :" + bool);
System.out.println("Byte :" + by);
System.out.println("Character:" + ch);
System.out.println("Double :" + d);
System.out.println("Float :" + f);
System.out.println("Integer :" + i);
System.out.println("Long :" + l);
System.out.println("Short :" + sh);
System.out.println("String :" + str);
}
}
执行结果
Bool :false
Byte :0
Character:
Double :0.0
Float :0.0
Integer :0
Long :0
Short :0
String :null
引用类型
在编程中,引用数据类型(或称为引用类型)是指那些在内存中存储对象的引用(即对象的地址)的数据类型。与基本数据类型(如 int
、char
)不同,引用数据类型存储的是对实际数据的引用,而不是数据本身。
引用数据类型的特点
- 存储方式:
- 引用数据类型存储的是对象在堆内存中的地址。实际的数据存储在堆内存中,而变量中存储的是对该对象的引用。
- 内存管理:
- 引用数据类型的对象存储在堆内存中,而不是栈内存。堆内存中的对象会在不再被引用时由垃圾回收器(Garbage Collector)自动清除。
- 对象的可变性:
- 引用数据类型的对象通常是可变的,即对象的状态(属性)可以在创建后发生改变。
- 在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。
- 对象、数组都是引用数据类型。
- 所有引用类型的默认值都是null。
- 一个引用变量可以用来引用任何与之兼容的类型。
- 例子:Site site = new Site(“Runoob”)。
常见的引用数据类型
类(Class)
-
在面向对象编程中,类是最常见的引用数据类型。类定义了对象的属性(字段)和方法(行为)。
-
示例:
public class Person { String name; int age; void greet() { System.out.println("Hello, my name is " + name); } } Person person = new Person(); person.name = "Alice"; person.age = 30; person.greet(); // 输出:Hello, my name is Alice
接口(Interface)
-
接口定义了一组方法,这些方法可以被实现接口的类所实现。接口本身不能被实例化,但可以用作引用数据类型。
-
示例:
interface Animal { void makeSound(); } class Dog implements Animal { public void makeSound() { System.out.println("Woof"); } } Animal myDog = new Dog(); myDog.makeSound(); // 输出:Woof
枚举(Enum)
-
定义:枚举用于定义一组常量值,通常用于表示有限的选项集合。
-
特点:枚举常量是枚举类型的实例。可以有方法和字段,但不能继承其他类。
-
示例:
public enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }
数组(Array)
-
定义:数组是一种引用数据类型,用于存储多个相同类型的元素。数组对象在堆内存中创建。
-
示例:
int[] numbers = new int[5]; numbers[0] = 10; numbers[1] = 20; System.out.println(numbers[0]); // 输出:10
集合(Collections)
-
定义:集合框架用于存储和操作对象的集合。常见的集合有列表、集合、映射等。
-
特点:提供了多种数据结构和算法,如
ArrayList
、HashSet
、HashMap
等。 -
示例:
import java.util.ArrayList; import java.util.HashMap; ArrayList<String> list = new ArrayList<>(); list.add("Apple"); list.add("Banana"); HashMap<String, Integer> map = new HashMap<>(); map.put("One", 1); map.put("Two", 2);
自定义数据结构
-
定义:自定义数据结构可以是自定义的类或接口,用于特定的业务需求。
-
特点:开发者可以根据需要设计数据结构,封装数据和操作。
-
示例:
public class Node { int value; Node next; Node(int value) { this.value = value; this.next = null; } }
字符串(String)
-
在Java中,
String
是一个引用数据类型,代表一个字符序列。虽然在语法上处理字符串看起来类似于基本数据类型,但String
实际上是一个对象。 -
示例:
String message = "Hello, World!"; System.out.println(message); // 输出:Hello, World!
包装类(Wrapper Classes)
-
定义:包装类用于将基本数据类型包装成对象。常见的有
Integer
、Double
、Character
等。 -
特点:包装类提供了基本数据类型的对象表示,可以与集合框架兼容。
-
示例:
Integer number = new Integer(10); Double pi = new Double(3.14);
泛型(Generics)
-
定义:泛型允许在定义类、接口或方法时使用类型参数。
-
特点:使得代码在处理不同类型的数据时更加通用和安全。
-
示例:
public class Box<T> { private T content; public void setContent(T content) { this.content = content; } public T getContent() { return content; } }
异常(Exception)
-
定义:异常是程序运行过程中出现的错误的对象。它们用于处理错误和异常情况。
-
特点:异常类通常继承自
Exception
或RuntimeException
。 -
示例:
try { int result = 10 / 0; } catch (ArithmeticException e) { System.out.println("Cannot divide by zero."); }
引用数据类型的比较
-
比较内容:
- 引用数据类型的比较通常比较对象的引用,即内存地址。使用
==
运算符比较两个对象的引用是否相同。 - 如果需要比较对象的实际内容,应使用类的
equals
方法(如果该类已重写了equals
方法)。
示例:
String str1 = new String("Hello"); String str2 = new String("Hello"); System.out.println(str1 == str2); // 输出:false,因为 str1 和 str2 是不同的对象 System.out.println(str1.equals(str2)); // 输出:true,因为 str1 和 str2 的内容相同
- 引用数据类型的比较通常比较对象的引用,即内存地址。使用
小结
引用数据类型在编程中用于创建和操作复杂的数据结构。它们提供了对对象的引用,并且对象的实际数据存储在堆内存中。理解引用数据类型对于编写面向对象的代码、管理内存和处理数据结构非常重要。
Java常量
在 Java 中,常量是指在程序执行过程中其值不能被改变的量。常量通常用于定义一些固定的值,这些值在程序运行期间不会发生变化。Java 中的常量可以通过以下几种方式声明:
使用 final
关键字
final
关键字用于声明一个不可变的变量,即一旦初始化后其值不能再改变。通常,常量会结合 static
关键字使用,以便在类的任何实例中都可以访问相同的常量值。
声明常量的语法final
关键字用于声明一个不可变的变量,即一旦初始化后其值不能再改变。通常,常量会结合 static
关键字使用,以便在类的任何实例中都可以访问相同的常量值。
声明常量的语法
public class Constants {
public static final int MAX_USERS = 100;
public static final String APP_NAME = "MyApp"
}
public
:常量的访问修饰符,允许其他类访问。static
:表示常量属于类而不是某个实例。final
:修饰变量,使其值不可修改。int
、String
:常量的数据类型。
接口中的常量
在 Java 中,接口中的字段隐式地被声明为 public static final
,因此可以在接口中定义常量。接口中的字段自动被认为是常量。
示例
public interface Config {
int TIMEOUT = 30; // 默认 public static final
String BASE_URL = "https://api.example.com";
}
使用接口中的常量
public class Main {
public static void main(String[] args) {
System.out.println("Timeout: " + Config.TIMEOUT);
System.out.println("Base URL: " + Config.BASE_URL);
}
}
枚举(Enum)中的常量
枚举是一种特殊的常量类型,用于定义一组固定的常量。枚举提供了类型安全的常量定义方式,并且可以包含字段、方法和构造函数。
示例
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
使用枚举常量
public class Main {
public static void main(String[] args) {
Day today = Day.FRIDAY;
System.out.println("Today is: " + today);
}
}
常量的命名约定
在 Java 中,常量通常使用全大写字母,并使用下划线分隔单词。这是一种命名约定,有助于提高代码的可读性和一致性。
示例
public class Constants {
public static final int MAX_ATTEMPTS = 5;
public static final String ERROR_MESSAGE = "An error occurred";
}
总结
Java 中常量的声明方式主要包括:
final
关键字:用于声明不可变的变量,常与static
一起使用。- 接口中的常量:隐式地为
public static final
。 - 枚举(Enum):用于定义一组固定的常量,提供类型安全的方式。
通过这些声明方式,Java 提供了灵活且安全的方法来定义和使用常量,帮助提高代码的可维护性和可读性。
特殊的转义字符序列
符号 | 字符含义 |
---|---|
\n | 换行 (0x0a) |
\r | 回车 (0x0d) |
\f | 换页符(0x0c) |
\b | 退格 (0x08) |
\0 | 空字符 (0x0) |
\s | 空格 (0x20) |
\t | 制表符 |
" | 双引号 |
’ | 单引号 |
\ | 反斜杠 |
\ddd | 八进制字符 (ddd) |
\uxxxx | 16进制Unicode字符 (xxxx) |
类型转换
在 Java 中,类型转换是一种将变量从一种数据类型转换为另一种数据类型的过程。Java 提供了几种类型转换的方式,主要包括以下几种
1、自动类型转换(隐式类型转换)
自动类型转换是由 Java 编译器自动完成的,他在转换过程中不会丢失信息。自动类型转换通常发生在较小范围的类型转换到较大的类型转换时。例如:
- 从
int
到long
、float
或double
- 从
float
到double
示例
int intValue = 10;
long longValue = intValue; // 自动类型转换,从 int 到 long
float floatValue = intValue; // 自动类型转换,从 int 到 float
double doubleValue = intValue; // 自动类型转换,从 int 到 double
转换从低级到高级。
低 ------------------------------------> 高
byte,short,char—> int —> long—> float —> double
数据类型转换必须满足如下规则:
-
不能对boolean类型进行类型转换。
-
不能把对象类型转换成不相关类的对象。
-
在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
-
转换过程中可能导致溢出或损失精度,例如:
int i =128; byte b = (byte)i;
因为 byte 类型是 8 位,最大值为127,所以当 int 强制转换为 byte 类型时,值 128 时候就会导致溢出。
-
浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入,例如:
(int)23.7 == 23; (int)-45.89f == -45
代码示例:
public class ZiDongLeiZhuan{
public static void main(String[] args){
char c1='a';//定义一个char类型
int i1 = c1;//char自动类型转换为int
System.out.println("char自动类型转换为int后的值等于"+i1);
char c2 = 'A';//定义一个char类型
int i2 = c2+1;//char 类型和 int 类型计算
System.out.println("char类型和int计算后的值等于"+i2);
}
}
运行结果
char自动类型转换为int后的值等于97
char类型和int计算后的值等于66
**解析:**c1 的值为字符 a ,查 ASCII 码表可知对应的 int 类型值为 97, A 对应值为 65,所以 i2=65+1=66
2、强制类型转换(显示类型转换)
强制类型转换需要显式地告诉编译器进行转换,并且可能会丢失信息或导致数据截断。通常用于将较大范围的类型转换为较小范围的类型
代码示例:
double doubleValue = 10.99;
int intValue = (int) doubleValue; // 强制类型转换,从 double 到 int,丢失小数部分
3、包装类和基本类型转换
Java 中的基本数据类型(如 int
、float
、double
等)可以通过相应的包装类(如 Integer
、Float
、Double
)进行转换。
代码示例:
// 基本类型到包装类
int intValue = 100;
Integer integerValue = Integer.valueOf(intValue); // 从 int 到 Integer
// 包装类到基本类型
Integer anotherInteger = 200;
int anotherIntValue = anotherInteger.intValue(); // 从 Integer 到 int
4、字符串和基本类型之间的转换
Java 提供了一些方法来将字符串转换为基本类型,或者将基本类型转换为字符串
代码示例
// 字符串到基本类型
String str = "123";
int intValue = Integer.parseInt(str); // 从 String 到 int
// 基本类型到字符串
int anotherIntValue = 456;
String anotherStr = Integer.toString(anotherIntValue); // 从 int 到 String
5、对象类型转换(向上转型和向下转型)
在面向对象编程中,类型转换也可以发生在对象之间。对象类型转换包括向上转型(将子类对象赋给父类引用)和向下转型(将父类引用赋给子类对象)。
向上转型
向上转型是指将子类对象赋给父类引用,这种转换是隐式进行的,不需要显式声明。
class Animal {
void makeSound() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
Animal animal = dog; // 向上转型
animal.makeSound(); // 可以调用父类方法
}
}
向下转型
向下转型是将父类引用转换回子类引用,这种转换可能会失败,需要显式声明,并且通常需要进行类型检查
public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
if (animal instanceof Dog) {
Dog dog = (Dog) animal; // 向下转型
dog.bark(); // 可以调用子类方法
}
}
}
6、使用 instanceof
运算符
instanceof
运算符用于检查对象是否时某个特定类型的实例。他可以在进行向下转向之前进行类型检查
if (someObject instanceof SomeClass) {
// 可以安全地进行向下转型
SomeClass someClassObject = (SomeClass) someObject;
}
总结
这篇文章的内容就到这里了,如果你感觉这篇文章对你有帮助的话请点赞、收藏 ➕ 关注。
感谢您的阅读,这里是开发小白,期待与您的下次相遇(●’◡’●) ~