校园网站开发的需求分析,辽宁工程招投标信息网,在济南什么人想做网站,网站建站建设哪家好1 Java可变长参数
1.1 概述
Java 的可变长参数#xff08;Varargs#xff09;是在 Java 1.5 中引入的功能#xff0c;允许方法接受任意数量的相同类型的参数。可变参数的语法是在参数类型后面加上三个点#xff08;...#xff09;#xff0c;例如 int... numbers。
1.…1 Java可变长参数
1.1 概述
Java 的可变长参数Varargs是在 Java 1.5 中引入的功能允许方法接受任意数量的相同类型的参数。可变参数的语法是在参数类型后面加上三个点...例如 int... numbers。
1.2 使用规则
可变参数必须放在参数列表的最后一位如果方法有多个参数可变参数必须放在最后。例如public void printNumbers(String prefix, int... numbers) {// 方法体
}只能有一个可变参数一个方法中只能有一个可变参数。
1.3 原理
当使用可变参数时Java 会在编译时创建一个数组数组的大小就是传入的可变参数的数量。然后将这些参数放入数组中并将数组传递给方法。
例如
public void printNumbers(int... numbers) {for (int number : numbers) {System.out.println(number);}
}调用 printNumbers(1, 2, 3) 时Java 会创建一个 int[] 数组 {1, 2, 3}然后传递给方法。
1.4 使用场景
可变参数通常用于需要处理任意数量相同类型对象的场景。例如
打印任意数量的整数计算任意数量的数字的和处理任意数量的字符串
1.5 注意事项 避免重载带有可变参数的方法重载带有可变参数的方法可能会导致编译器无法确定调用哪个方法从而引发编译错误。例如 public void print(String... args) {// 方法体
}public void print(String arg1, String... args) {// 方法体
}调用 print(a) 时编译器无法确定是调用第一个方法还是第二个方法。 明确指示如果必须重载带有可变参数的方法确保在调用时明确指示参数避免编译器混淆。
1.6 示例代码
public class VarargsExample {public static void main(String[] args) {printNumbers(1, 2, 3);printNumbers(4, 5);printNumbers();}public static void printNumbers(int... numbers) {for (int number : numbers) {System.out.println(number);}}
}2 Java native方法
2.1 概念
本地方法Native Method是用 native 关键字修饰的方法通常不需要用 Java 语言实现。本地方法允许 Java 代码调用其他语言如 C/C编写的代码。
2.2 JNIJava Native Interface
JNIJava Native Interface是 Java 平台的一部分从 Java 1.1 开始引入允许 Java 代码与其他语言编写的代码进行交互。JNI 主要用于以下场景
标准 Java 类库不支持的功能调用已有的 C/C 库提高性能特别是在需要接近硬件或运行次数特别多的方法中
2.2.1 JNI 的优点
扩展 Java 功能可以通过 JNI 调用其他语言编写的库。性能优化在某些情况下使用本地代码可以提高性能。
2.2.2 JNI 的缺点
跨平台性丧失本地代码通常不跨平台需要在不同系统环境下重新编译。安全性降低本地代码的不当使用可能导致程序崩溃。
2.3 用 C 语言编写本地方法
2.3.1 步骤
编写带有 native 方法的 Java 类生成 .java 文件。编译 Java 类生成 .class 文件。生成头文件使用 javah -jni 或 javac -h 生成 .h 文件。实现本地方法使用 C/C 实现 .h 文件中的方法生成 .c 或 .cpp 文件。生成动态链接库将 C/C 编写的文件生成动态链接库如 .dll 或 .so。
2.3.2 示例HelloWorld 程序 编写 Java 类 public class HelloJNI {static {System.loadLibrary(hello); // 加载动态链接库}public native void sayHello(); // 声明本地方法public static void main(String[] args) {new HelloJNI().sayHello(); // 调用本地方法}
}编译 Java 类 javac HelloJNI.java生成头文件 javac -h . HelloJNI.java这将生成 HelloJNI.h 文件。 实现本地方法 #include jni.h
#include HelloJNI.h
#include stdio.hJNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject obj) {printf(Hello, JNI!\n);
}编写编译脚本 # compile.sh
gcc -I$JAVA_HOME/include -I$JAVA_HOME/include/darwin -dynamiclib -o libhello.dylib HelloJNI.c执行脚本 sh compile.sh运行 Java 程序 java HelloJNI2.4 JNI 调用 C 的流程图
Java 代码 - JNI 接口 - 本地代码 (C/C)2.5 native 关键字 native 用于修饰方法表示该方法的实现在外部定义通常用 C/C 实现。 语法 修饰方法的位置必须在返回类型之前。不能用 abstract 修饰没有方法体。返回值可以是任意类型。 native 方法示例
public native void sayHello();2.6 小结
JNI 允许 Java 代码与其他语言编写的代码进行交互扩展了 Java 的功能。本地方法 用 native 关键字修饰通常用于调用 C/C 库或提高性能。注意事项使用 JNI 会丧失跨平台性且本地代码的不当使用可能导致程序崩溃。
3 Java构造方法
3.1 概念
构造方法Constructor是 Java 中的一种特殊方法用于在创建对象时初始化对象的状态。每次使用 new 关键字创建对象时构造方法至少会被调用一次。如果没有显式定义构造方法编译器会提供一个默认的无参构造方法。
3.2 创建构造方法的规则
名称与类名相同构造方法的名称必须与类名完全一致。无返回类型构造方法没有返回类型包括 void。不能是抽象的、静态的、最终的、同步的 抽象构造方法不能被子类继承因此用 abstract 修饰没有意义。静态构造方法用于初始化对象因此用 static 修饰没有意义。最终构造方法不能被子类继承因此用 final 修饰没有意义。同步多个线程不会同时创建内存地址相同的同一个对象因此用 synchronized 修饰没有必要。
3.3 语法格式
class class_name {public class_name(){} // 默认无参构造方法public ciass_name([paramList]){} // 定义有参数列表的构造方法…// 类主体
}3.4 默认构造方法
无参构造方法如果构造方法没有任何参数它就是一个无参构造方法。默认构造方法如果类中没有显式定义构造方法编译器会自动提供一个无参构造方法。目的主要为对象的字段提供默认值。代码示例
public class DefaultConstructorExample {private int value;// 编译器提供的默认构造方法public DefaultConstructorExample() {this.value 0; // 默认值}public static void main(String[] args) {DefaultConstructorExample obj new DefaultConstructorExample();System.out.println(obj.value); // 输出: 0}
}3.5 有参构造方法
有参数的构造方法可以有一个或多个参数用于为不同的对象提供不同的初始值。替代方案如果没有有参构造方法可以通过 setter 方法为字段赋值。代码示例
public class ParameterizedConstructorExample {private String name;public ParameterizedConstructorExample(String name) {this.name name;}public static void main(String[] args) {ParameterizedConstructorExample obj new ParameterizedConstructorExample(Java);System.out.println(obj.name); // 输出: Java}
}3.6 重载构造方法
构造方法重载通过提供不同的参数列表来重载构造方法。编译器会根据参数的数量和类型来决定调用哪一个构造方法。代码示例
public class OverloadedConstructorExample {private int id;private String name;public OverloadedConstructorExample(int id) {this.id id;}public OverloadedConstructorExample(int id, String name) {this.id id;this.name name;}public static void main(String[] args) {OverloadedConstructorExample obj1 new OverloadedConstructorExample(1);OverloadedConstructorExample obj2 new OverloadedConstructorExample(2, Java);System.out.println(obj1.id); // 输出: 1System.out.println(obj2.id obj2.name); // 输出: 2 Java}
}3.7 构造方法和方法的区别
特性方法构造方法目的反映对象的行为初始化对象的字段返回类型可以有返回类型没有返回类型调用方式明确的开发者通过代码决定调用隐式的通过编译器完成编译器提供不会由编译器提供如果没有明确提供无参构造方法编译器会提供名称可以和类名相同也可以不同必须和类名相同
3.8 复制对象
复制一个对象可以通过以下三种方式完成
通过构造方法使用另一个对象作为参数来创建新对象。通过对象的值手动复制对象的每个字段。通过 Object 类的 clone() 方法实现 Cloneable 接口并重写 clone() 方法。
通过构造方法
public class CopyConstrutorPerson {private String name;private int age;public CopyConstrutorPerson(String name, int age) {this.name name;this.age age;}public CopyConstrutorPerson(CopyConstrutorPerson person) {this.name person.name;this.age person.age;}public void out() {System.out.println(姓名 name 年龄 age);}public static void main(String[] args) {CopyConstrutorPerson p1 new CopyConstrutorPerson(沉默王二,18);p1.out();CopyConstrutorPerson p2 new CopyConstrutorPerson(p1);p2.out();}
}在上面的例子中有一个参数为 CopyConstrutorPerson 的构造方法可以把该参数的字段直接复制到新的对象中这样的话就可以在 new 关键字创建新对象的时候把之前的 p1 对象传递过去。
通过对象的值
public class CopyValuePerson {private String name;private int age;public CopyValuePerson(String name, int age) {this.name name;this.age age;}public CopyValuePerson() {}public void out() {System.out.println(姓名 name 年龄 age);}public static void main(String[] args) {CopyValuePerson p1 new CopyValuePerson(沉默王二,18);p1.out();CopyValuePerson p2 new CopyValuePerson();p2.name p1.name;p2.age p1.age;p2.out();}
}直接拿 p1 的字段值复制给 p2 对象p2.name p1.name
通过 Object 类的 clone() 方法
public class ClonePerson implements Cloneable {private String name;private int age;public ClonePerson(String name, int age) {this.name name;this.age age;}Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}public void out() {System.out.println(姓名 name 年龄 age);}public static void main(String[] args) throws CloneNotSupportedException {ClonePerson p1 new ClonePerson(沉默王二,18);p1.out();ClonePerson p2 (ClonePerson) p1.clone();p2.out();}
}通过 clone() 方法复制对象的时候ClonePerson 必须先实现 Cloneable 接口的 clone() 方法然后再调用clone()方法ClonePerson p2 (ClonePerson) p1.clone()。
3.9 小结
构造方法虽然没有返回值但返回的是类的对象。初始化字段只是构造方法的一种工作它还可以做更多比如启动线程、调用其他方法等。
4 思维导图 参考链接 Java可变参数详解5分钟教会我妹 手把手教你用 C语言实现 Java native 本地方法 Java构造方法打开Java对象创建之门的钥匙