那我们加快速度,基础运算、条件和循环直接跳过,先学 Java 相对 C++ 更需要注意的"对象与引用、参数传递"。 这些会直接影响你后面写类、数组和算法题。
对象与引用
对象
java
public class Main {
public static void main(String[] args) {
Student a = new Student();
System.out.println(a.score);
a.score = 90;
System.out.println(a.score);
Student b = a;
b.score = 100;
System.out.println(a.score);
System.out.println(b.score);
}
}
class Student {
int score;
}
Java中,类类型变量保存的是对对象的引用。这里b=a并没有赋值一个新的对象,而是让b和a引用同一个对象。
如果是C++形式上类似于
Student a; //不能写new Student()因为这里是定义对象,下面是定义指针
a.score=90;
Student b=a; //这里
a,b是两个独立对象b.score=100; //此时a.score=90而b.score=100
实质上则类似于
Student *a=new Student();
a->score=90;
Student *b=a; //有两个指针,但只有一个学生对象
b->score=100; //此时a.score=100,b.score=100
数组
java
public class Main {
public static void main(String[] args) {
int[] a={1, 2, 3, 4, 5};
int[] b=a;
b[0]=10;
System.out.println(a[0]);
System.out.println(b[0]);
}
}
指定数组长度可以用int\[\] a=new int5;这样类似的语句。
// 指定长度,元素默认是 0
int\[\] a = new int5;
// 根据初始元素确定长度,这里长度是 3
int\[\] b = {1, 2, 3};
// 另一种带初始元素的写法
int\[\] c = new int\[\]{1, 2, 3};
但不能同时在方括号里指定长度、又列出初始元素:,比如int\[\] d=new int3{1,2,3}。
在这里,int\[\] b=a复制的是引用,整个过程都只创建了一个数组对象,但是可以通过a和b访问初始元素。
如果要复制出独立数组,那么用int\[\] b=a.clone();,这样就互不干扰了。
练习:这段代码的输出?
java
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] a = {1,2,3};
int[] b = a;
b[0] = 10;
b = new int[]{7,8,9};
b[1] = 20;
System.out.println(a[0]);
System.out.println(a[1]);
System.out.println(b[0]);
System.out.println(b[1]);
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
}
}
显然是a=10, 2, 3 b=7, 20, 9。
Java 方法
定义、调用、返回值,以及 static 怎么用
java
public class Main {
static int add(int a, int b){
return a+b;
}
public static void main(String[] args) {
int a=5, b=10;
int sum=add(a,b);
System.out.println("Sum of "+a+" and "+b+" is: "+sum);
}
}
add 和 main 都写在 Main 类里,彼此并列,不能把 add 定义在 main 内部。
为什么这里加 static?
因为我们希望在静态的 main 函数里调用 int sum=add(a,b)。同一个类中它也可以写成 int sum=Main.add(a,b)。
那么如果去掉这个static呢?就没法直接调用了,这个就是普通的实例方法,需要这么先创建对象,再通过对象调用写:
Main obj=new Main();
int sum=obj.add(a,b);
问:现在看这个内容,我是否可以理解为,这个Main对象可以自己创建自己?为什么?Main obj=new Main();int sum=obj.add(a,b);
答:可以在 Main 类的代码里创建 Main 对象。不过更准确地说,是"main 方法执行了创建对象的语句",不是"对象创建自己"。
注意这两个名字不同:
Main:类名。main:方法名,是程序入口。
执行过程是:
- Java 启动程序,执行静态方法
main,这时不需要先有Main对象。- 执行
new Main(),创建一个Main对象。- 将这个对象的引用保存到变量
obj。- 执行
obj.add(3, 5),调用这个对象的普通方法。
返回值是数组的情况
java
import java.util.Arrays;
public class Main {
static int[] create(int number){
int[] total = new int[number];
for(int i = 0; i < number; i++){
total[i] = i;
}
return total;
}
public static void main(String[] args) {
System.out.println(Arrays.toString(create(5)));
}
}
最后是一个练习
用同一个学生类逐步增加功能。
你要逐步弄明白:
new Student("小明", 90)怎么把数据放进对象------构造方法。- 两个对象为什么能保存不同成绩------实例成员变量。
- 参数
score和成员变量score重名怎么办------this.score。- 怎样阻止外部随意写入负数成绩------
private与方法校验。- 怎样统计总共创建了多少个学生对象------
static成员变量。这一阶段的验收:不照抄,写出一个学生类,能在创建时设置姓名和成绩,修改成绩时检查范围,并输出学生信息。 能完成并解释代码,就继续学字符串和集合,不用提前钻反射、JVM 等内容。
java
public class Main {
public static void main(String[] args) {
Student a = new Student("小明", 21, 90);
Student b = new Student("小红", 22, 85);
a.showInfo();
b.showInfo();
a.setScore(95);
a.showInfo();
a.setScore(-10);
a.showInfo();
System.out.println("创建的学生对象数:" + Student.getCount());
}
}
class Student{
private String name;
private int age;
private int score;
private static int count = 0;
Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
count++;
}
public void showInfo(){
System.out.println("Name: " + name + ", Age: " + age + ", Score: " + score);
}
public void setScore(int score) {
if (score < 0 || score > 100){
System.out.println("Invalid score. Please enter a score between 0 and 100.");
return;
}
this.score = score;
}
public static int getCount() {
return count;
}
}