Java的工作方式
Java的工作流程[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oQ74ynTM-1679202802445)(G:\Typora图片所在\image-20230310194245246.png)]
write once, and work everywhere!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fn12ZgVX-1679202802446)(G:\Typora图片所在\ZSSDMld.png)]
Java程序设计概述
关键术语
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZvoJq8zW-1679202802447)(G:\Typora图片所在\image-20230310195852945.png)]
动态性
Java是一种静态类型语言,这意味着在编译时就需要确定每个变量的类型。但是,Java也具有一些动态性,主要体现在以下几个方面:
-
反射:Java中的反射机制允许程序在运行时动态地获取类的信息,并且可以在运行时创建对象、调用方法等。这种动态性使得Java程序更加灵活,可以根据需要动态地加载和使用类。
-
动态代理:Java中的动态代理机制允许程序在运行时动态地创建代理类,从而可以在不修改原始类的情况下对其进行增强或扩展。这种动态性使得Java程序更加易于扩展和维护。
-
动态绑定:Java中的方法调用是通过动态绑定来实现的。这意味着在运行时,程序会根据对象的实际类型来确定调用哪个方法。这种动态性使得Java程序更加灵活,可以根据实际情况动态地调用不同的方法。
总之,Java的动态性使得它在编写灵活、可扩展的程序方面具有优势。
基本语法/规则
- 大小写敏感:Java 是大小写敏感的,这就意味着标识符 Hello 与 hello 是不同的。
- 类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass 。
- 方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
- 源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记 Java 是大小写敏感的),文件名的后缀为 .java。(如果文件名和类名不相同则会导致编译错误)。
- 主方法入口:所有的 Java 程序由 public static void main(String[] args) 方法开始执行。
修饰符
像其他语言一样,Java可以使用修饰符来修饰类中方法和属性。主要有两类修饰符:
- 访问控制修饰符 : default, public , protected, private
- 非访问控制修饰符 : final, abstract, static, synchronized
修饰符用来定义类、方法或者变量,通常放在语句的最前端。
访问控制修饰符
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。
-
default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。接口里的变量都隐式声明为 public static final,而接口里的方法默认情况下访问权限为 public。
-
private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
声明为私有访问类型的变量只能通过类中公共的 getter 方法被外部类访问。
-
public : 对所有类可见。使用对象:类、接口、变量、方法
-
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
非访问修饰符
static 修饰符
-
静态变量:
static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。
-
静态方法:
static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。
final 修饰符
- final 变量:
final 表示"最后的、最终的"含义,变量一旦赋值后,不能被重新赋值。
被 final 修饰的实例变量必须显式指定初始值。
final 修饰符通常和 static 修饰符一起使用来创建类常量。
- final 方法
父类中的 final 方法可以被子类继承,但是不能被子类重写。
声明 final 方法的主要目的是防止该方法的内容被修改。
- final 类
final 类不能被继承,没有类能够继承 final 类的任何特性。
abstract 修饰符
- 抽象类:
抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。
一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类, 否则将出现编译错误。
抽象类可以包含抽象方法和非抽象方法。
- 抽象方法
抽象方法是一种没有任何实现的方法,该方法的具体实现由子类提供。
抽象方法不能被声明成 final 和 static。
任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。
如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。
抽象方法的声明以分号结尾,例如:public abstract sample();
public abstract class SuperClass{
abstract void m(); //抽象方法
}
class SubClass extends SuperClass{
//实现抽象方法
void m(){
.........
}
}
synchronized 修饰符
synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。
volatile 修饰符
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
一个 volatile 对象引用可能是 null。
变量
Java 中主要有如下几种类型的变量
- 局部变量
- 类变量(静态变量)
- 成员变量(非静态变量)
在使用变量时需要遵循的原则为:就近原则
首先在局部范围找,有就使用;接着在成员位置找。
静态变量: 由static修饰的变量称为静态变量,其实质上就是一个全局变量。如果某个内容是被所有对象所共享,那么该内容就应该用静态修饰;没有被静态修饰的内容,其实是属于对象的特殊描述。
public class Variable{
static int allClicks=0; // 类变量
String str="hello world"; // 实例变量
public void method(){
int i =0; // 局部变量
}
}
局部变量
- 局部变量声明在方法、构造方法或者语句块中;
- 局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;
- 访问修饰符不能用于局部变量;
- 局部变量只在声明它的方法、构造方法或者语句块中可见;
- 局部变量是在栈上分配的。
- 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。
实例变量
- 实例变量声明在一个类中,但在方法、构造方法和语句块之外;
- 当一个对象被实例化之后,每个实例变量的值就跟着确定;
- 实例变量在对象创建的时候创建,在对象被销毁的时候销毁;
- 实例变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息;
- 实例变量可以声明在使用前或者使用后;
- 访问修饰符可以修饰实例变量;
- 实例变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把实例变量设为私有。通过使用访问修饰符可以使实例变量对子类可见;
- 实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。变量的值可以在声明时指定,也可以在构造方法中指定;
- ==实例变量可以直接通过变量名访问。但在静态方法以及其他类中,就应该使用完全限定名:==ObjectReference.VariableName。
类变量(静态变量)
- 类变量也称为静态变量,在类中以 static 关键字声明,但必须在方法之外。
- 无论一个类创建了多少个对象,类只拥有类变量的一份拷贝。
- 静态变量除了被声明为常量外很少使用,静态变量是指声明为 public/private,final 和 static 类型的变量。静态变量初始化后不可改变。
- 静态变量储存在静态存储区。经常被声明为常量,很少单独使用 static 声明变量。
- 静态变量在第一次被访问时创建,在程序结束时销毁。
- 与实例变量具有相似的可见性。但为了对类的使用者可见,大多数静态变量声明为 public 类型。
- 默认值和实例变量相似。数值型变量默认值是 0,布尔型默认值是 false,引用类型默认值是 null。变量的值可以在声明的时候指定,也可以在构造方法中指定。此外,静态变量还可以在静态语句块中初始化。
- 静态变量可以通过:ClassName.VariableName的方式访问。
- ==类变量被声明为 public static final 类型时,类变量名称一般建议使用大写字母。==如果静态变量不是 public 和 final 类型,其命名方式与实例变量以及局部变量的命名方式一致。
Java的基本程序设计结构
Java类名要求
Java中的类名必须以字母开头,后面是字母和数字的任意组合。
Java中的类名必须以字母、下划线或美元符号开头,后面可以是字母、数字、下划线或美元符号的任意组合。但是,建议遵循以下命名规则:
- 类名应该以大写字母开头,采用驼峰命名法,例如:MyClass、MyFirstJavaClass。
- 如果类名由多个单词组成,则每个单词的首字母都应该大写,例如:MyFirstJavaClass。
- 类名应该是有意义的,能够描述该类的作用。
- 避免使用Java的保留字作为类名。
Java通用语法:object.method(parameters)
System.out.println(); //可以输出一个空行
数据类型
由于Java在所有平台上的运行结果都一样,所以需要特别固定各种数据类型的取值范围!
-
整型
- int 4字节 -20亿~20亿
- short 2字节
- long 8字节,后缀L或l
- byte 1字节 -128~127
- 十六进制前缀0x/0X,八进制前缀0,二进制0b/0B
- 可以用1_000_000来表示数字,属于语法糖的一种!
- Java中没有任何无符号类型的整型,但是可以同各国Interger和Long类来处理无符号。
-
浮点类型
-
float 4字节
-
double 8字节;巧记,越长越准
-
这是因为在二进制中,只能使用 2 的幂次方来表示分数,例如 1/2、1/4、1/8 等。而 1/10 的分数形式在二进制中是无限循环小数,即 0.0001100110011…,因为它不能被有限个二进制位精确表示,所以在计算机中表示十进制小数时会存在精度误差。这个问题可以通过使用特殊的十进制浮点数格式(如 IEEE 754)来解决,但仍然存在精度误差的问题。
-
Double.POSITIVE_INFINITY Double.NEGTIVE_INFINITY Double.NaN 正负无穷大和非数字
-
如果不允许有任何舍入误差,使用BigDecimal类
-
-
char类型
- 字面量值要用单引号括起来,比如'A' - 可以表示为十六进制的值,从'\u0000'到'\uFFFF' - *强烈建议不要在程序中使用char类型,作为抽象数据类型处理??*那可以直接用String类型
-
boolean类型
-
false/true
-
整型和boolean类型不能相互转换!
-
变量与常量
-
变量
-
变量名必须以字母开头并且由字母或数字构成的序列,提倡逐行声明每个变量。
-
声明变量后,必须要显式初始化!
-
局部变量可以通过变量的初始值推断, var greeting = “Hello”;
-
-
常量
-
final用于指示常量,表示这个变量只能被赋值一次,习惯上,常量名全部大写!
-
若是希望某个常量可以在一个类中多个方法中使用,可以用类常量,static final来定义
-
public static final double CM_PER_INCH=2.54;
- 枚举类型
enum Size {SMALL, MEDIUM, LARGE, EXTRA_LARGE};
Size s = Size.MEDIUM;
运算符
Math.PI Math.E
不要将boolean类型和其他类型进行强制类型转换,防止错误,但是可以用三元运算符 b?1:0
建议不要使用++,让人困惑,实在不行可以使用后++
^ | 如果相对应位值相同,则结果为0,否则为1 | (A ^ B)得到49,即 0011 0001 |
---|---|---|
〜 | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0。 | (〜A)得到-61,即1100 0011 |
instanceof 运算符
该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。
( Object reference variable ) instanceof (class/interface type)
String name = "James";
boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真
字符串
Character类
// 原始字符 'a' 装箱到 Character 对象 ch 中
Character ch = 'a';
// 原始字符 'x' 用 test 方法装箱
// 返回拆箱的值到 'c'
char c = test('x');
序号 | 方法与描述 |
---|---|
1 | isLetter() 是否是一个字母 |
2 | isDigit() 是否是一个数字字符 |
3 | isWhitespace() 是否是一个空白字符 |
4 | isUpperCase() 是否是大写字母 |
5 | isLowerCase() 是否是小写字母 |
6 | toUpperCase() 指定字母的大写形式 |
7 | toLowerCase() 指定字母的小写形式 |
8 | toString() 返回字符的字符串形式,字符串的长度仅为1 |
String类
- String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了
- 和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
-
如果需要对字符串进行修改推荐使用 StringBuffer。
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。
-
使用说明
输入输出
控制流
大数
数组
数组的基础操作
-
数组是储存在堆上的对象,可以保存多个同类型变量。
-
声明和创建数组:
dataType[] arrayRefVar = new dataType[arraySize];
dataType[] arrayRefVar = {value0, value1, …, valuek};
-
数组作为函数的参数
public static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
- 数组作为函数的返回值
public static int[] reverse(int[] list) {
int[] result = new int[list.length];
for (int i = 0, j = result.length - 1; i < list.length; i++, j--) {
result[j] = list[i];
}
return result;
}
- 多维数组
int[][] a = new int[2][3];
Arrays类
序号 | 方法和说明 |
---|---|
1 | public static int binarySearch(Object[] a, Object key) 用二分查找算法在给定数组中搜索给定值的对象(Byte,Int,double等)。数组在调用前必须排序好的。如果查找值包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。 |
2 | public static boolean equals(long[] a, long[] a2) 如果两个指定的 long 型数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 |
3 | public static void fill(int[] a, int val) 将指定的 int 值分配给指定 int 型数组指定范围中的每个元素。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 |
4 | public static void sort(Object[] a) 对指定对象数组根据其元素的自然顺序进行升序排列。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 |
引用类型
- 在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。
- 对象、数组都是引用数据类型。
- 所有引用类型的默认值都是null。
- 一个引用变量可以用来引用任何与之兼容的类型。
- 例子:Site site = new Site(“Runoob”)。
java和c++的引用区别
在Java中,类实例声明和构造是分开。"T a;"是声明,而"a=new T();"才是构造。引用声明和C++相同。但是Java的机制与C++不同,Java中的引用也叫句柄,或者说句柄才是其真实名称。类声明的都是一个句柄,调用构造函数才会使得句柄指向类实例。因此Java中没有类似于C++中的复制函数,因为Java的复制都是直接复制句柄内容。例如"T b=a;"只不过是将a的句柄复制(赋值)给了b,从而b也指向a指向的类实例。可以看出Java与C++在此处的不同,Java依然只有一个实例,而C++则存在了两个实例。
所以在函数中,Java的形参都是入参的句柄复制,并且是浅复制(只复制该句柄,而不复制句柄指向的下一层句柄)。因此在函数中,直接修改形参是不能改变入参的。但是如果修改形参指向的对象的下一层句柄则会修改入参。因此在Java中不存在像C/C++中一样的Swap函数。函数的返回值,也是句柄复制。如果在函数中构造一个局部变量类实例,那么是可以返回到外部的,当然那个局部变量的句柄是不存在了。
Java中要复制对象,需要重载clone函数,并且要分清是浅复制还是深复制(完全构造一个新对象,两者的内部数据和实例不相同)。
c++ 与java引用具体比较:
c++中一个引用指向的地址不会改变,改变的是指向地址的内容,然而java中引用指向的地址在变!!
如果非要对比着看,那么Java中的“引用”倒是和C/C++的指针更像一些,和C++的“引用”很不一样。
java去除指针概念,就用引用…
你看 java:
A a = new A(1);
A b = new A(2);
b = a;
没有问题,a 和 b引用同一个对象A(2),原来的A(1)成为没有被引用的对象。 垃圾回收机制会在之后的某个时刻把A(1)干掉。
而C++则不然。C++的引用就语义上说是“别名”【本质是个const指针,又叫指针常量】,而并不是指针的另一种用法:
A a = A(1);
A b = A(2);
A& c = b; //c 是 b的别名
c = a; //并不是 c 引用 a,而是拷贝操作 c.operator= ( a )
就语言机制来说,java的引用是用来管理和命名对象;
而,C++的引用机制是很纯粹的,就是别名而已。
java的引用机制是一个很复杂的机制。他必须区分“基本对象”和“复合对象”,你可以想象一下,如果其中没有基本对象,那么我们如何完成对象的复制? 唯一的解决方案是提供两个等于号,或者一律用构造函数… 但是综合来看,他和垃圾回收形成了相当完美的组合方案
数据类型转换规则
数据类型转换必须满足如下规则:
-
\1. 不能对boolean类型进行类型转换。
-
\2. 不能把对象类型转换成不相关类的对象。
-
\3. 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
-
\4. 转换过程中可能导致溢出或损失精度,例如:
-
\5. 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入
-
\6. 条件是转换的数据类型必须是兼容的。
-
\6\1. 格式:(type)value type是要强制类型转换后的数据类型 实例:
byte b = (byte)i1;//强制类型转换为byte
Java Number & Math类
- 封装:所有的包装类**(Integer、Long、Byte、Double、Float、Short)**都是抽象类 Number 的子类。
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wJJVW4m8-1679202802448)(G:\Typora图片所在\OOP_WrapperClass.png)]
- 常用的一些方法:
1 | xxxValue() 将 Number 对象转换为xxx数据类型的值并返回。 |
---|---|
2 | compareTo() 将number对象与参数比较。 |
3 | equals() 判断number对象是否与参数相等。 |
4 | valueOf() 返回一个 Number 对象指定的内置数据类型 |
5 | toString() 以字符串形式返回值。 |
6 | parseInt() 将字符串解析为int类型。 |
7 | abs() 返回参数的绝对值。 |
8 | ceil() 返回大于等于( >= )给定参数的的最小整数,类型为双精度浮点型。 |
9 | floor() 返回小于等于(<=)给定参数的最大整数 。 |
10 | rint() 返回与参数最接近的整数。返回类型为double。 |
11 | round() 它表示四舍五入,算法为 Math.floor(x+0.5),即将原来的数字加上 0.5 后再向下取整,所以,Math.round(11.5) 的结果为12,Math.round(-11.5) 的结果为-11。 |
与对象有关的术语
- 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
- 类:类是一个模板,它描述一类对象的行为和状态。
- 方法:方法就是行为,一个类可以有很多方法。逻辑运算、数据修改以及所有动作都是在方法中完成的。
- 实例变量:每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定。
类是对现实生活中一类具有共同属性和行为的事物的抽象,一个类有多个对象。
人以群分,物以类聚!
构造方法
-
每个类都有构造方法。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。
-
在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。
public class Puppy{
public Puppy(){
}
public Puppy(String name){
// 这个构造器仅有一个参数:name
}
}
- 为什么要构造方法?
- 这边说若没有显示为类定义构造方法,则会提供一个默认的,可是之前在rate项目中就不可以。
public class Puppy{
int puppyAge;
public Puppy(String name){
// 这个构造器仅有一个参数:name
System.out.println("小狗的名字是 : " + name );
}
public void setAge( int age ){
puppyAge = age;
}
public int getAge( ){
System.out.println("小狗的年龄为 : " + puppyAge );
return puppyAge;
}
public static void main(String[] args){
/* 创建对象 */
Puppy myPuppy = new Puppy( "tommy" );
/* 通过方法来设定age */
myPuppy.setAge( 2 );
/* 调用另一个方法获取age */
myPuppy.getAge( );
/*你也可以像下面这样访问成员变量 */
System.out.println("变量值 : " + myPuppy.puppyAge );
}
}
源文件声明规则
- 一个源文件中只能有一个 public 类
- 一个源文件可以有多个非 public 类
- 源文件的名称应该和 public 类的类名保持一致。例如:源文件中 public 类的类名是 Employee,那么源文件应该命名为Employee.java。
- 如果一个类定义在某个包中,那么 package 语句应该在源文件的首行。
- 如果源文件包含 import 语句,那么应该放在 package 语句和类定义之间。如果没有 package 语句,那么 import 语句应该在源文件中最前面。
- import 语句和 package 语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。
Java正则表达式
Java方法
方法的命名规则
- 1.方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。
- 2.下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。一个典型的模式是:test_,例如 testPop_emptyStack
方法的定义
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xAY3yG7s-1679202802449)(G:\Typora图片所在\D53C92B3-9643-4871-8A72-33D491299653.jpg)]
命令行参数的使用
有时候你希望运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现。
命令行参数是在执行程序时候紧跟在程序名字后面的信息。
实例
下面的程序打印所有的命令行参数
public class CommandLine {
public static void main(String[] args){
for(int i=0; i<args.length; i++){
System.out.println("args[" + i + "]: " + args[i]);
}
}
}
如下所示,运行这个程序:
$ javac CommandLine.java
$ java CommandLine this is a command line 200 -100
args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100
构造方法
当一个对象被创建时候,构造方法用来初始化该对象。构造方法和它所在类的名字相同,但构造方法没有返回值。
通常会使用构造方法给一个类的实例变量赋初值,或者执行其它必要的步骤来创建一个完整的对象。
不管你是否自定义构造方法,所有的类都有构造方法,因为 Java 自动提供了一个默认构造方法,默认构造方法的访问修饰符和类的访问修饰符相同(类为 public,构造函数也为 public;类改为 protected,构造函数也改为 protected)。
一旦你定义了自己的构造方法,默认构造方法就会失效。
无参数的构造方法
// 一个简单的构造函数
class MyClass {
int x;
// 以下是构造函数
MyClass() {
x = 10;
}
}
public class ConsDemo {
public static void main(String[] args) {
MyClass t1 = new MyClass();
MyClass t2 = new MyClass();
System.out.println(t1.x + " " + t2.x);
}
}
有参数的构造方法
// 一个简单的构造函数
class MyClass {
int x;
// 以下是构造函数
MyClass(int i ) {
x = i;
}
}
public class ConsDemo {
public static void main(String[] args) {
MyClass t1 = new MyClass( 10 );
MyClass t2 = new MyClass( 20 );
System.out.println(t1.x + " " + t2.x);
}
}
可变参数
JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。
方法的可变参数的声明如下所示:
typeName… parameterName
在方法声明中,在指定参数类型后加一个省略号(…) 。
==一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。==任何普通的参数必须在它之前声明。
举个栗子:
public class VarargsDemo {
public static void main(String[] args) {
// 调用可变参数的方法
printMax(34, 3, 3, 2, 56.5);
printMax(new double[]{1, 2, 3}); //这里也可以用数组,妙也!
}
public static void printMax( double... numbers) {
if (numbers.length == 0) {
System.out.println("No argument passed");
return;
}
double result = numbers[0];
for (int i = 1; i < numbers.length; i++){
if (numbers[i] > result) {
result = numbers[i];
}
}
System.out.println("The max value is " + result);
}
}
finalize() 方法
Java 允许定义这样的方法,它在对象被垃圾收集器析构(回收)之前调用,这个方法叫做 finalize( ),它用来清除回收对象。
例如,你可以使用 finalize() 来确保一个对象打开的文件被关闭了。