Loading... ## 数据类型 - `float` 不可以这样赋初值:`float f1=3.14159` 因为这样默认是一个 `double` 型的。所以需要在末尾添加 `F/f` 来更改默认。例如:`float f2=3.14159F` - 比较逆天的一个点,参考下面的代码: ```java public class test { public static void main(String[] args) { int i = 1; i = i * 0.1; System.out.println(di); } } ``` 如果你是 C++ 选手,肯定认为这没有问题。但是 Java 是不支持这样乘的。所以要注意这样 **类型不同的乘法** 类似的:`char c = c1 + c2 - 1` 也是不合法的。同样要用强制类型转换。 ### `Array` v.s. `ArrayList` ### Array(数组) **定义:** - 数组是一个固定大小的、同类型元素的有序集合。 **特性:** 1. **大小固定:** - 创建数组时需要指定大小,且大小不能改变。 ```java int[] numbers = new int[5]; // 创建一个包含5个整数的数组 ``` 2. **类型限制:** - 数组中的所有元素必须是相同类型。 ```java String[] names = {"Alice", "Bob", "Charlie"}; ``` 3. **访问和修改:** - 可以通过索引访问和修改数组中的元素。 ```java numbers[0] = 10; // 将第一个元素设置为10 int firstNumber = numbers[0]; // 获取第一个元素的值 ``` ### ArrayList(动态数组) **定义:** - `ArrayList` 是一个可变大小的、同类型元素的有序集合,它是 Java 集合框架的一部分。 **特性:** 1. **大小可变:** - 可以动态增加或减少元素,大小会自动调整。 ```java ArrayList<Integer> numbers = new ArrayList<>(); // 创建一个整数的ArrayList numbers.add(10); // 添加元素10 numbers.add(20); // 添加元素20 ``` 2. **类型限制:** - `ArrayList` 是一个泛型类,可以指定存储的元素类型。 ```java ArrayList<String> names = new ArrayList<>(); names.add("Alice"); names.add("Bob"); ``` 3. **访问和修改:** - 可以通过索引访问和修改元素,也可以使用 `add`, `remove` 等方法进行操作。 ```java names.set(0, "Charlie"); // 修改第一个元素为"Charlie" String firstName = names.get(0); // 获取第一个元素的值 names.remove(1); // 移除第二个元素 ``` 4. **更多方法:** - 提供了很多有用的方法,如 `size()`, `contains()`, `indexOf()` 等。 ```java int size = names.size(); // 获取ArrayList的大小 boolean hasAlice = names.contains("Alice"); // 检查是否包含"Alice" ``` ### 比较 - **大小**:数组大小固定,`ArrayList` 大小可变。 - **性能**:数组访问速度快,`ArrayList` 有额外的开销(如自动调整大小)。 - **灵活性**:`ArrayList` 提供更多的方法和灵活性。 一句话,类似于数组和 `std::vector` 的关系。 ## 类 - `static` 关键词: - static method: used without calling object, cannot access instance variables and non-static methods. - static variable: belongs to the class, only one copy per class - `final` 关键字在 Java 中有三种主要用法: 1. **变量**:当一个变量被声明为 `final` 时,它的值在初始化之后不能被改变。 2. **方法**:当一个方法被声明为 `final` 时,它不能被子类重写。 3. **类**:当一个类被声明为 `final` 时,它不能被继承。 - Checked and Unchecked Exception - **Unchecked exceptions** 是指 `RuntimeException` 类及其子类。 - 编译器不会强制程序员处理这些异常。 - 由于未检查异常对应于程序错误,因此程序出现这种异常时通常会终止(而不是尝试从问题中恢复)。 - **Checked exceptions** 是 `Exception` 类的子类,但不包括 `RuntimeException` 及其子类。 - 编译器强制程序员以某种方式处理这些异常。 - 通常程序可以从这些问题中恢复(而不是终止)并继续运行。 - Exceptions Handling - ![image-20240602185501705](/Users/xinzeli/Library/Application Support/typora-user-images/image-20240602185501705.png) - 如果声明了某一个 method 需要 `throws` 某个 `Exception` ,那么其中必须要有地方 `throw` 相关的。 - 一般来说会写这样的结构: ```java try { // Do something } catch (Exception e) { // catch the Exceptions throw new Exception() // throw exception } ``` ## 泛型 Generecis ### 什么是泛型? **定义:** - 泛型允许类、接口和方法操作应用于任意类型,提供了编写更通用代码的能力。 ### 使用泛型的好处 1. **类型安全**: - 编译时检查类型错误,避免运行时的 `ClassCastException`。 ```java List<String> list = new ArrayList<>(); list.add("Hello"); // list.add(123); // 编译错误,避免了类型错误 ``` 2. **消除强制类型转换**: - 泛型消除了在代码中频繁出现的强制类型转换。 ```java List<String> list = new ArrayList<>(); list.add("Hello"); String str = list.get(0); // 不需要强制类型转换 ``` 3. **代码重用性**: - 泛型使得相同的代码可以用于多种不同的类型,增加了代码的重用性和灵活性。 ```java public class Box<T> { private T value; public void set(T value) { this.value = value; } public T get() { return value; } } Box<Integer> intBox = new Box<>(); intBox.set(123); Box<String> strBox = new Box<>(); strBox.set("Hello"); ``` ### 泛型的使用 1. **泛型类**: - 定义一个使用泛型的类。 ```java public class GenericClass<T> { private T data; public GenericClass(T data) { this.data = data; } public T getData() { return data; } public void setData(T data) { this.data = data; } } GenericClass<Integer> intObj = new GenericClass<>(10); GenericClass<String> strObj = new GenericClass<>("Hello"); ``` 2. **泛型方法**: - 定义一个使用泛型的静态或实例方法。 ```java public class GenericMethod { public static <T> void printArray(T[] array) { for (T element : array) { System.out.print(element + " "); } System.out.println(); } } Integer[] intArray = {1, 2, 3, 4, 5}; String[] strArray = {"A", "B", "C"}; GenericMethod.printArray(intArray); GenericMethod.printArray(strArray); ``` 3. **泛型接口**: - 定义一个使用泛型的接口。 ```java public interface GenericInterface<T> { void performAction(T value); } public class GenericInterfaceImpl implements GenericInterface<String> { @Override public void performAction(String value) { System.out.println("Value: " + value); } } GenericInterface<String> obj = new GenericInterfaceImpl(); obj.performAction("Hello"); ``` ### 泛型的边界 1. **上界通配符**: - 限制泛型类型必须是某个类或其子类。 ```java public static void printNumbers(List<? extends Number> list) { for (Number num : list) { System.out.println(num); } } List<Integer> intList = Arrays.asList(1, 2, 3); List<Double> doubleList = Arrays.asList(1.1, 2.2, 3.3); printNumbers(intList); printNumbers(doubleList); ``` 2. **下界通配符**: - 限制泛型类型必须是某个类或其父类。 ```java public static void addNumbers(List<? super Integer> list) { list.add(1); list.add(2); } List<Number> numList = new ArrayList<>(); addNumbers(numList); ``` ### 泛型的限制 - 泛型类型不能是基本类型(如 `int`、`char`)。 - 不能创建泛型类型的实例。 - 不能在静态上下文中使用泛型类型参数。 ## IO ### Input / Output(输入/输出) #### 简单输入/输出 - Java 有许多不同的输入输出方式,如 `FileReader`, `FileWriter`, `FileOutputStream`, `FileInputStream`, `PrintWriter`, `PrintStream` 等。 - 这里仅介绍基本的 I/O 方法:从键盘输入/输出到屏幕,从文件输入/输出到文件。 #### 流(Stream) - 在 Java 中,输入/输出流是表示输入数据源或输出数据目标的对象。 - Java 程序默认有三个流: - `System.in` 是标准输入流,通常表示键盘输入。 - `System.out` 是标准输出流,通常表示屏幕输出。 - `System.err` 是标准错误流,通常表示错误信息的屏幕输出。 ### 屏幕输出 - 使用 `System.out.print` 和 `System.out.println` 可以进行基本的屏幕输出。 - 使用 `System.out.printf` 可以进行格式化输出,例如: ```java System.out.printf("hello world%n"); System.out.printf("hello %-4d world %10.4f%n", 2, 3.4); ``` ### 键盘输入 - 使用 `Scanner` 对象可以方便地从 `System.in` 读取输入。 - `Scanner` 类提供了多种方法读取不同类型的输入,如 `nextLine`, `nextInt`, `nextDouble`, `nextBoolean` 等。 - 例子: ```java import java.util.Scanner; public class Test { public static void main(String[] args) { Scanner s = new Scanner(System.in); System.out.print("Type some text: "); while(s.hasNext()) { String str = s.nextLine(); System.out.println("The text is: " + str); System.out.print("Type some text: "); } System.out.println("No more input."); } } ``` ### 文件输出 - 最简单的写入文本文件的方法是创建一个 `PrintWriter` 对象。 - 如果文件不存在,会创建一个新文件;如果文件已存在,旧内容会被删除。 - 例子: ```java import java.io.FileNotFoundException; import java.io.PrintWriter; public class Test { public static void main(String[] args) { try { PrintWriter out = new PrintWriter("mydata.txt"); out.print("hello"); out.println(" world"); out.printf("hello world%n"); out.printf("hello %-4d world %10.4f%n", 2, 3.4); out.close(); } catch(FileNotFoundException ex) { System.err.println(ex.getMessage()); } } } ``` ### 文件输入 - 最简单的从文本文件读取的方法是创建一个 `File` 对象,然后使用 `Scanner` 对象读取文件内容。 - 例子: ```java import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class Test { public static void main(String[] args) { File f = new File("mydata.txt"); try { Scanner s = new Scanner(f); while(s.hasNext()) { String str = s.nextLine(); System.out.println("The file text is: " + str); } s.close(); } catch(FileNotFoundException ex) { System.err.println(ex.getMessage()); } } } ``` ### 对象输入/输出 - 如果使用 `println` 方法将对象写入屏幕或文件,Java 只会打印对象的类型和地址。 - 可以覆盖 `toString` 方法来实现对象的友好显示。 - 例子: ```java public class Circle { private int x; private int y; private double radius; public Circle(int x, int y, double radius) { this.x = x; this.y = y; this.radius = radius; } @Override public String toString() { return "(Circle " + x + " " + y + " " + radius + ")"; } public static void main(String[] args) { Circle c = new Circle(10, 20, 30.0); System.out.println(c); } } ``` ### 对象序列化 - Java 提供了一种简单的方法来序列化对象:只需实现 `Serializable` 接口。 - 可以使用 `readObject` 和 `writeObject` 方法将对象读写到二进制文件。 - 例子: ```java import java.io.*; public class Circle implements Serializable { private int x; private int y; private double radius; public Circle(int x, int y, double radius) { this.x = x; this.y = y; this.radius = radius; } public static void main(String[] args) { Circle c1 = new Circle(10, 20, 30.0); try { FileOutputStream fo = new FileOutputStream("mydata.bin"); ObjectOutputStream out = new ObjectOutputStream(fo); out.writeObject(c1); out.close(); fo.close(); } catch(IOException e) { System.err.println(e.getMessage()); } try { FileInputStream fi = new FileInputStream("mydata.bin"); ObjectInputStream in = new ObjectInputStream(fi); Circle c2 = (Circle) in.readObject(); in.close(); fi.close(); System.out.println("c2 radius: " + c2.radius); } catch(IOException | ClassNotFoundException e) { System.err.println(e.getMessage()); } } } ``` **特别重要的就是,输出的时候一定要 throw IOException;如果是 ObjectInputStream,还要 throw ClassNotFoundException** ### 总结 - 简单输入/输出 - 文件输入/输出 - 对象输入/输出 - 对象序列化 最后修改:2024 年 06 月 02 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 1 如果觉得我的文章对你有用,请随意赞赏