JAVA基础

devtools/2024/10/18 17:58:40/

1.数据类型

变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。

内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。

1.1 基本数据类型

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;
  • 例子:

    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';。

可以通过相应的包装类的内置属性,打印出最大值以及

java">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);  }  
}

类型默认值:

1.2 引用数据类型

引用类型是指存储对象或数组的引用(地址),而不是存储实际的值。通过引用,程序可以访问对象或数组的属性和方法。

在 Java 中,主要有以下几种引用类型:

  • 对象类型(Object Types)

    • 通过类(class)定义的对象属于引用类型。例如:StringArrayList、用户定义的类等。
  • 数组类型(Array Types)

    • 数组是一个引用类型,可以存储同一类型的多个值。例如:int[]String[] 等。

对象或者数组的默认值是NULL。

1.3 基本数据类型之间的转换

整型、实型(常量)、字符型数据可以混合运算。

运算中,不同类型的数据先转化为同一类型,然后进行运算。

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

自动类型转换通常发生在如下几种情况中:

  1. 低精度到高精度的转换,包括:

    • byteshortchar 之间的自动提升。
    • intlong 之间的自动提升。
    • 浮点数从小类型到大类型。
  2. 非数值类型到数值类型的转换。

  3. Wrapper类到基本类型的转换。

例如:

java">byte b = 10;
short s = b;  // 隐式转换,从 byte 到 short
int i = s;    // 隐式转换,从 short 到 int
float f = i;  // 隐式转换,从 int 到 float

在自动类型转换中,你需要注意的是避免由于溢出或精度缺失导致的不准确结果。例如,将一个非常大的整数赋值给一个更小的整数类型可能会导致数据截断。

1.3.2 强制类型转换(显式转换)

显式类型转换通常需要用户明确指定转换的类型,即使用(目标类型)来包裹要转换的表达式或变量。

  1. 从高精度到低精度的转换。
  2. 从一个数值类型到另一个数值类型的转换。
  3. 从数值类型到字符或布尔类型的转换。

例如:

java">float f = 10.5f;
int i = (int) f;  // 显示转换,从 float 到 int,结果为 10

在强制类型转换中,需要注意的是可能会引起数据丢失。例如,将一个浮点数转换为整数时,浮点数的小数部分会直接被忽略。

隐含强制类型转换

  • 1、 整数的默认类型是 int。

  • 2. 小数默认是 double 类型浮点型,在定义 float 类型时必须在数字后面跟上 F 或者 f。

1.4 引用数据类型之间的转换

1.4.1 类类型之间的转换

1. 向上转型(Upcasting)

向上转型是指将子类引用赋值给父类引用。这个过程是安全的,因为子类是父类的扩展,父类引用能够包含子类对象。

java">class Parent {void display() {System.out.println("Parent");}
}class Child extends Parent {void display() {System.out.println("Child");}
}Parent parent = new Child(); // 向上转型
parent.display(); // 输出 "Child"

在向上转型时,请注意以下几点:

  • 不会发生数据丢失。
  • 在父类引用中只能访问父类定义的方法和属性,如果需要访问子类特有的方法,需要进行向下转型。

2. 向下转型(Downcasting)

向下转型是指将父类引用赋值给子类引用。这个过程是可能不安全的,因为如果父类引用实际上指向的是一个不同的类型(而不是目标子类的对象),将会引发ClassCastException

java">Parent parent = new Child(); // 向上转型
Child child = (Child) parent; // 向下转型

在向下转型时,需要注意:

  • 确保父类引用指向的确实是子类对象,否则会抛出ClassCastException
  • 推荐使用instanceof操作符,返回 true 或者 false 进行检查。
java">if (parent instanceof Child) {Child child = (Child) parent; // 安全的转换
}

使用instanceof:在进行向下转型之前,使用instanceof可以有效避免转换错误。

1.4.2 接口类型之间的转换

1. 实现接口的类之间的转换

Java允许类实现多个接口,可以在接口之间进行转换。确保实际对象实现了所转换到的接口。如果不实现,转换将失败。

java">interface Animal {void makeSound();
}class Dog implements Animal {public void makeSound() {System.out.println("Woof");}
}Animal animal = new Dog(); // 向上转型
Dog dog = (Dog) animal; // 向下转型

在接口类型转换时的注意事项:

  • 使用instanceof检查对象是否实现了目标接口。
java">if (animal instanceof Dog) {Dog dog = (Dog) animal; // 安全的转换
}

1.4.3 数组类型转换

Java中的数组也是引用类型,数组类型之间的转换需要注意以下几点:

  • 数组的向上转型,例如,将一个String[]引用赋给Object[],是安全的,因为所有数组的父类是Object
java">String[] stringArray = new String[5];
Object[] objArray = stringArray; // 向上转型

  • 当进行向下转型时,需要确保实际的数组对象类型与目标类型一致。
java">Object[] objArray = new String[5];
String[] stringArray = (String[]) objArray; // 安全的转换

如果尝试将不同类型的数组进行向下转型,会引发ArrayStoreException

1.4.4 向上转型拿不到子类的特有成员

为何无法通过父类引用访问子类特有的方法?

  1. 类型擦除(编译阶段):父类引用视图的对象类型是 Animal即使实际引用的是 Dog,编译器只知道 animal 是一种 Animal,因此只能使用 Animal 类中定义的方法。编译器在编译时只查找 Animal 类的方法,不会考虑 Dog 中的特有方法。

  2. 静态类型(编译类型)与动态类型(运行类型)

    • 静态类型 是指声明变量时的类型(在上面的例子中,animal 的静态类型是 Animal)。
    • 动态类型 是指实际引用的对象类型(在这里是 Dog)。
    • 由于编译器在编译时仅依赖于静态类型,它无法知道在运行时实际引用的是 Dog,因此只能使用 Animal 的方法。

因此只能通过向下转型来实现访问子类的特有成员。

那为什么访问子类和父类的共同方法,会优先调用子类的方法呢?

  1. 动态绑定:Java采用动态绑定(或称晚绑定)来决定在运行时哪个方法应被调用。即使使用父类引用来调用方法,Java会查看实际对象的类型(动态类型)而不是引用类型(静态类型),然后调用实际对象的实现。

1.5 数组

Java 语言中提供的数组是用来存储固定大小的同类型元素。

创建数组的三种方式:

java">dataType[] arrayRefVar = new dataType[arraySize];
java">dataType[] arrayRefVar = {value0, value1, ..., valuek};
java">// new dataType[]{value0, value1, ..., valuek} , 这里的[]不要写大小
// 因为编译器识别不出{}里面的数据占了多少
dataType[] arrayRefVar = new dataType[]{value0, value1, ..., valuek};

注意事项:

  • 数组大小固定,一旦创建后不能更改,如果需要动态大小,可以考虑使用 ArrayList 等集合类。

数组常用的方法:

  • Arrays.copyOf(数组,指定拷贝长度) 方法进行数组复制。
  • Arrays.sort() 方法对数组进行排序。
  • Arrays.binarySearch() 方法可以在已排序的数组中查找元素。
  • Arrays.toString() 方法,可以将数组转换为字符串

1.6 String、StringBuffer、StringBuild

1. String

  • 不可变性String 对象一旦创建,其内容不可更改。如果对 String 进行修改(比如拼接),会生成一个新的 String 对象,原有字符串保持不变。

  • 性能:由于每次修改都需要创建新的对象,频繁操作会导致性能开销较大。

  • 线程安全:由于不可变性,String 是线程安全的。

  • 使用场景:适合使用在字符串内容不会改变的场合,如常量字符串。

示例

java">String str = "Hello";
str += " World"; // 生成新的 String 对象

2. StringBuffer

  • 可变性StringBuffer 是可变的,意味着在原有对象上执行修改操作时,不会生成新的对象。

  • 性能:由于是可变的,在执行较多的字符串操作(如拼接、插入、删除等)时,性能优于 String

  • 线程安全StringBuffer 是线程安全的,所有方法都是同步的,因此适合在多线程环境中使用。

  • 使用场景:适合在多线程环境中进行字符串操作的场合。

示例

java">StringBuffer sb = new StringBuffer("Hello");
sb.append(" World"); // 修改原有对象

3. StringBuilder

  • 可变性:与 StringBuffer 类似,StringBuilder 也是可变的,专为字符串操作设计。

  • 性能:性能优于 StringBuffer,因为 StringBuilder 的方法不是同步的,它的性能更高。

  • 线程安全StringBuilder 不是线程安全的,不适合在多线程环境中使用。

  • 使用场景:适合在单线程环境下进行大量字符串操作。

示例

java">StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // 修改原有对象

2.Iterator(迭代器)

2.1 集合实现好的迭代器

Iterator(迭代器)是 Java 集合框架中的一种机制,是一种用于遍历集合(如列表、集合和映射等)的接口。

它提供了一种统一的方式来访问集合中的元素,而不需要了解底层集合的具体实现细节。

Java Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,可用于迭代 ArrayList 和 HashSet 等集合。

Iterator 是 Java 迭代器最简单的实现,ListIterator 是 Collection API 中的接口, 它扩展了 Iterator 接口。

迭代器接口定义了几个方法,最常用的是以下三个:

  • next() - 返回迭代器的下一个元素,并将迭代器的指针移到下一个位置。

  • hasNext() - 用于判断集合中是否还有下一个元素可以访问。

  • remove() - 从集合中删除迭代器最后访问的元素(可选操作)。

代码演示:

java">// 引入 ArrayList 和 Iterator 类
import java.util.ArrayList;
import java.util.Iterator;public class RunoobTest {public static void main(String[] args) {// 创建集合ArrayList<String> sites = new ArrayList<String>();sites.add("Google");sites.add("Runoob");sites.add("Taobao");sites.add("Zhihu");// 获取迭代器Iterator<String> it = sites.iterator();// 输出集合中的所有元素while(it.hasNext()) {System.out.println(it.next());}}
}

2.2 自定义迭代器

有一个需求就是普通数据也想用迭代器,那必须得自己封装...

封装迭代器:

java">package demo;import java.util.Iterator;public class MyDataStructure implements Iterable<Integer> {private  int arr[];public MyDataStructure(int[] arr) {this.arr = arr;}@Overridepublic Iterator<Integer> iterator() {return new MyIterator();}private class MyIterator implements Iterator<Integer>{private int index = 0;@Overridepublic boolean hasNext() {return index < arr.length;}@Overridepublic Integer next() {return arr[index++];}}
}

使用迭代器:

java">package demo;import java.util.Iterator;public class TestIterator {public static void main(String[] args) {int arr[] = new int[]{11,22,33};MyDataStructure mds = new MyDataStructure(arr);// 增强for循环
//        for (int num : mds) {
//            System.out.println(num);
//        }Iterator<Integer> iterator = mds.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}}
}

注意:由于增强For循环也是迭代器实现的,因此也可以使用增强For循环。。。


http://www.ppmy.cn/devtools/125134.html

相关文章

Centos基线自动化检查脚本

此脚本是一个用于检查Linux系统安全配置的Bash脚本。它通过多项安全标准对系统进行评估&#xff0c;主要检查以下内容&#xff1a; IP地址获取&#xff1a;脚本首先获取主机的IP地址&#xff0c;确保其以10.115开头。 密码策略检查&#xff1a; 检查最小密码长度&#xff08;P…

理解Web3的互操作性:不同区块链的连接

随着Web3的迅速发展&#xff0c;互操作性成为区块链技术中的一个核心概念。互操作性指的是不同区块链之间能够无缝地交流和共享数据&#xff0c;从而实现更加高效和灵活的生态系统。本文将探讨Web3中互操作性的意义、面临的挑战以及未来的发展趋势。 1. 互操作性的意义 在Web…

2025 - 中医学基础 - 考研 - 职称

2025 - 中医学基础 - 考研 - 职称 第1章 中医学导论 1.中医学的指导思想是&#xff08;&#xff09;( ) [单选] A&#xff0e;阴阳学说 B&#xff0e;五行学说 C&#xff0e;精气学说 D&#xff0e;整体观念 E&#xff0e;辨证论治 正确答案: D 2.中医学的理论核心是&…

常用STL容器(c++)

目录 一、vector容器---动态数组 1.为什么要引进动态数组&#xff1f; 2.引用库 3.构造一个动态数组 4.一些增删查改动态数组的方法 5.使用基础的vector 6.构造函数 7.二维动态数组 二、set()容器---集合 1.构造一个集合 2.方法 2.1插入元素 2.2判断元素是否存在 …

【最新华为OD机试E卷-支持在线评测】跳房子I(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

Python 网络爬虫:从入门到实践

在大数据时代&#xff0c;网络爬虫&#xff08;Web Scraping&#xff09;是一项重要的技术&#xff0c;能帮助我们从互联网上获取大量的信息。Python 以其简洁的语法和丰富的库支持&#xff0c;成为实现网络爬虫的首选语言。本文将详细介绍Python网络爬虫的基础知识、常用库&am…

Java对接支付宝支付接口

在Java中对接支付宝支付接口&#xff0c;通常需要使用支付宝提供的开放平台API。以下是一个基本的步骤指南&#xff0c;帮助你开始&#xff1a; 1. 注册支付宝开发者账号 首先&#xff0c;你需要在支付宝开放平台注册一个开发者账号。注册完成后&#xff0c;你需要创建一个应…

使用 Cesium 实现气象可视化的详细教程

Cesium 是一个基于 WebGL 的开源 JavaScript 库&#xff0c;常用于构建三维地球和地图应用。通过结合 Cesium 与气象数据&#xff0c;我们可以实现逼真的气象可视化效果&#xff0c;例如展示温度场、降雨量、风速等气象现象。本文将详细介绍如何使用 Cesium 实现气象数据的可视…