Java学习之基本语法2

2025.7.30

1.上节课内容回顾:

cb5b463290add60bb7948f3227e0023.png

2.Java的引用类型和值类型的机制

package com.lx.chapter1;

public class Test3 {
	int a = 10;
	//方法中基本数据类型的值传递,传递的是这个值的副本,无法改变原始定义的值。
	//而引用类型传递的是地址(指针),传递的是所指向对象的地址
	public static void setA(int a) // a =a;
	{
		a = 200;
	}
	public static void setA(Test3 t1) // Test3 t1 = t1;
	{
		t1.a = 200;
	}
	public static void main(String[] args) {

		int a = 10;
		setA(a); // 是a是值类型,传递的是a的副本
		System.out.println(a);// 10 传递的是基本数据类型,传递的这个值的副本,无法改变原始定义的值。
		System.out.println("---------");
		Test3 t1 = new Test3();
		setA(t1);// t1是引用类型,传递的是t1的地址
		System.out.println(t1.a);// 200
	}
}

练习 例1:

package com.lx.chapter1;

///如果是引用类型赋值,实际是把赋值的对象的地址给被赋值的对象,说白了,被赋值的对象和赋值对象的地址是一样的。

///如果是引用类型赋值,就是改变对象的指向。

public class Test2 {
	
	 int  a =10;
	
	public static void main(String[] args) {
		
		Test2 t1  = new Test2();
		System.out.println(t1.a);//10
		
		Test2  t2 = t1;
		
		Test2  t3 =  new Test2();
		t2=t3;
		
		t2.a  =100;
		System.out.println(t1.a);//100  10
		
	}

}

练习 例2:

package com.lx.chapter1;

public class Test {

	//类的实例变量
	int  a  = 10 ;
	
	public Test()
	{
	   a = 100;
	}
	
	public Test(int a)//方法的参数,局部变量
	{
		a = 200;
	}
	
	//Java中引用类型的赋值,实际就是把地址赋值给声明的引用类型对象
	public  Test(Test  t)//Test t = t1; //引用类型
	{
		t.a =300;
	}
	
	public static void main(String[] args) {
		
	  //在main函数中创建这个类Test对象
	   Test  t1  = new Test();
	   System.out.println("Test类中t1.a的值为:"+ t1.a);//100
	   
	   Test  t3  = new Test(t1);// t3.a =10; 
	   System.out.println("Test类中t3.a的值为:"+ t3.a);//10
	   System.out.println("Test类中t1.a的值为:"+ t1.a);//300
	   
	   
	   
	   Test  t2  = new Test(50);
	   System.out.println("Test类中t2.a的值为:"+ t2.a);//10
	   
	
	}

}

3.for循环和函数调用执行机制

package com.lx.chapter1;

public class Test6 {
	
	
	static  boolean   foo(char a)
	{
		System.out.print(a);
		return  true;
	}
	public static void main(String[] args) {
		
		int  i = 0;
		//for循环三个参数
		//第一个参数,对for全局起到一个初始化的作用,所以最先被调用,且只会被调用一次
		//第二个参数,对于每次进入的变量进行判断,true则进,false则出,所以除了初始化以外第一个被调用判断的表达式
		//第三个参数,是for循环每一次完成动作之后进行的一次变量刷新动作,故第三个被调用
//问下面的for循环的输出结果是什么呢?
		for(foo('a'); i<2 &&  foo('b'); foo('d'))                            
		{
			foo('c');
			i++;//1  2
		}
	}

}

答案:abcdbcd

4.this关键字

package com.lx.chapter2;

public class Test {
	
	int  a  =10;
	
	Test()
	{
		//this关键字表示当前对象。当前对象是谁?哪个对象去调用,this实际就是那个对象
//这里的this就指代当前类的名字Test,Test中有一个属性为a,故this.a就是访问上述的int a = 10;
		this.a =100;
	}
	
	Test(int a)
	{
		//this关键字表示当前对象.而非传入参数的int a
		this.a =200;
	}
	
	public static void main(String[] args) {
		
		Test  t1   =new Test();
		System.out.println(t1.a);
		
		Test  t2   =new Test(100);
		System.out.println(t2.a);
		
		//this表示的是:哪个对象去调用,this实际就是哪个对象
		
		System.out.println(t1 == t2);
	}

}

package com.lx.chapter2;

/**
 * this表示当前对象;当前对象是谁,一定要搞明白,谁调用,this就是谁。
 * this(),表示调用本类中的构造函数 ,()表示构造函数参数列表
 *
 * this()必须在第一行,也只能在第一行,只能是一个。
 * this关键字不能在static函数和块中使用,static关键字不能使用this关键字
 * @author lixin
 *
 */

public class Stu {
	
	int  age  =100;
	
	public  Stu()
	{
		this(10);
		System.out.println("11111");
	}
	public Stu(int age)
	{
		
	}
	public Stu(String  name)
	{
		
	}
	
	public  void  show()
	{
		this.age =300;
	}
	
	public static void check()
	{
		  this.age =400;
	}

	
	public static void main(String[] args) {
		
		//this.age =200;
		
		//this.age =400;
	}

}

5.Java的静态块和匿名构造块

形如static{

//静态块的代码

}

被称为静态块

package com.lx.chapter2;
public class Test2 {
	//静态块  ,最先被加载,只执行一次,不能手动调用
	//最先被加载条件是:main所在的位置
	static {
		System.out.println("这是静态块1");
	}
	
	static{
		System.out.println("这是静态块2");
	}
	
	//匿名构造块  匿名:没有名字  不受参数限制,创建对象会隐式的自动的被调用执行,创建对象一次执行一次
	{
		System.out.println("这是匿名构造块");
	}
	
	Test2()
	{
		System.out.println("这是无参数的构造函数");
	}
	
	Test2(int a)
	{
		System.out.println("带参数a的构造函数");
		
	}
	
	public static void main(String[] args) {
		
		Test2 t2   = new Test2(100);
		
		Test2  t1   =new Test2();
		
	}
	
	

}

/**
 *   Java是为分布式而生,Sun公司为了小型设备互联互通而设计的编程语言,本来面目。
 *   
 *   ---
 *  
 *   Java面向对象(一个类,类的继承(多个类),扩展到抽象类和接口)-仓颉   ArkTS
 *   
 *   Java高并发多线程
 *   
 *   Java反射和注解
 *   
 *   Java分布式  RMI,webservice、thrift、GRPC
 *   
 *   A项目 ---------remote------------- B项目
 *   A设备-------------remote  call------B设备
 * 
 * 
 * 
 */

6.封装

封装,概念就是把类的属性私有化,用private关键字修饰,限制其他类的直接访问。其他类在调用一个类的私有属性时只能通过该类的getter,setter或者其他方法来间接调用.

为什么叫封装,正因为就好像你需要某个东西你没法直接上手获得你要的东西,必须要先打开拉链,才能获得其中的东西一样,里面的东西被容器封住了,也许是口袋,也许是集装箱,而我们的私有化就类似这种把东西用容器装起来的过程,所以被简称为封装。

我们用一个例子来更好描述这一过程:

Manager类

package com.lx.chapter4;

//封装:面向对象的思想的一个特征

//封装:参照生活:  每个人衣服的口袋,口袋  会装  钱,钥匙,身份证,是你个人重要的属性(这个属性就是变量)
public class Employee {
	//私有属性
	private double  salary;
	//缺省(其他类仍能访问)属性
	String  address;
	
	//设置值(setter)
	public  void  setSalary(double  salary)
	{
		if(salary>5000.0)
		{
			this.salary  = salary;
		}
		else
		{
			System.out.println("对不起,设置的数据不合法");
		}
		
	}
	
	//获取值(getter)
	public  double  getSalary(String str)
	{
		if(str.equals("manager"))
		{
			return this.salary;
		}
		return 0.0;
	
	}
	
	

}

User类

package com.lx.chapter4;

public class User {
	
	public static void main(String[] args) {
		Employee  e  = new Employee();
		
		
		//没有private,直接访问,不安全
		
		//加上private,不能直接访问,体现了安全性
		
		//System.out.println(e.salary);
		
		
		//间接访问,通过方法,可以在方法的内部进行业务控制
		e.setSalary(10000.0);
		
		double  dv = e.getSalary("emp");
		System.out.println(dv);
		

		
		double  dv1 = e.getSalary("manager");
		System.out.println(dv1);
		
	}

}

package com.lx.chapter4;

public class User {
	
	public static void main(String[] args) {
		Employee  e  = new Employee();
		
		
		//没有private,直接访问,不安全
//可能会导致很多类在调用修改一个属性,但只修改了一次,导致数据错乱
		
		//加上private,不能直接访问,体现了安全性
		
		//System.out.println(e.salary);
		
		
		//间接访问,通过方法,可以在方法的内部进行业务控制
		e.setSalary(10000.0);
		
		double  dv = e.getSalary("emp");
		System.out.println(dv);
		

		
		double  dv1 = e.getSalary("manager");
		System.out.println(dv1);
		
	}

}

7.方法重载&多态

在一个类中,有相同的方法名,不同的参数列表(不同的返回值类型),叫做方法重载

这是Java多态在一个类中的具体特征和体现

多态:同一个方法名,不同的实现结果

一个类中的具体特征和体现:编译时多态,调用哪个 play方法,是由参数的列表决定的。

参数的列表是在编译期间就确定的,所以叫做编译时多态。

package com.lx.chapter4;


public class Student {
	
	//银行卡号   封装  是面向对象编程思想的一个具体的特征和体现
	private  String   bankNum;
	
	public  void  play()
	{
		System.out.println("学生喜欢苏超");
	}
	
	public  String  play(String  game)
	{
		System.out.println("学生喜欢玩:"+game);
		
		return "ok";
	}
	
	public static void main(String[] args) {
		
		Student  s   = new Student();
//调用的就是无参方法
		s.play();
		
	}
	
	

}

我们可以从编译运行的文件更好诠释多态这一现象

当我们对文件进行编译的时候,会产生一个.class文件,这就是我们的编辑器能识别并使用的文件(此时文件再怎么改动都不会发生变化)

image (14).png

所以在编译时方法多次重载,我们解决问题时就能用一种方法更好地去解决出现的各种问题,多态越强,解决能力越强。

package com.lx.chapter4;


public class Student {
	
	//银行卡号   封装  是面向对象编程思想的一个具体的特征和体现
	private  String   bankNum;
	
	
	//在一个类中,有相同的方法名,不同的参数列表(不同的返回值类型),方法的重载
	
	
	//多态:同一个方法名,不同的实现结果 

	//一个类中的具体特征和体现:编译时多态,调用哪个 play方法,是由参数的列表决定的。

	//参数的列表是在编译期间就确定的,所以叫做编译时多态。
	
	//方法的重载  == 编译时多态  他们是一个意思
	
	//static修饰的,有相同的方法名,不同的参数列表(不同的返回值类型),还是方法的重载,还是编译型多态
	public  static   void  play()
	{
		System.out.println("学生喜欢苏超");
	}
	
	public static  String  play(String  game)
	{
		System.out.println("学生喜欢玩:"+game);
		
		return "ok";
	}
	
	public static void main(String[] args) {
		
		Student  s   = new Student();
		//使用的是带string参数的方法
		s.play("雷电");
		
	}
	
	

}

我们编辑器中所使用的JDK就自带很多种方法,其中也不乏多态的例子,如:

String类中的valueOf方法

image (15).png

Random类nextInt方法

package com.lx.chapter4;

import java.util.Random;

public class Test {
	
	public static void main(String[] args) {
		
		String  s1 = String.valueOf(10);
		
		String  s2 = String.valueOf(true);
		
		Random  r =  new Random();  //ctrl+shirt+o
		System.out.println(r.nextInt()); //随机数产生没有范围
		System.out.println(r.nextInt(100));//随机数产生限定范围
		
	}

}

一些小知识

package com.lx.chapter4;


//类的全局变量,可以赋值,也可以不赋值,如果不赋值,是采用类型的默认值
//方法的局部变量,定义可以不赋初始值,在使用时一定要赋初始值,否则报错。
public class Manager {
	
	//类的全局变量,全局变量,可以初始化不赋值,是采用类型的默认值
	int  a ;
	
	private  double salary  = 5000;
	
	
	public void  show()
	{
		//局部变量,存在于方法体内,定义可以不赋初始值,在使用时一定要赋初始值,否则报错。
		//int count =0 ;
		int count;
		//System.out.println(count); //报错
	}
	
	public static void main(String[] args) {
		
		Manager  m  = new Manager();
		System.out.println(m.a);
	}
	
	

}

package com.lx.chapter4;

public class Test1 {
	
    //引用类型的默认值是:null
	Test1  t ;
	
	//对比字符串""和null区别
	String  s = "";  //""和null," "空字符串,null:空对象  
	//String  s ;  
	
	
	Integer i = -1;
	
	public void show()
	{
		System.out.println(s.hashCode());// 输出对象的哈希码
	}
	
	public static void main(String[] args) {
		
		Test1  t1   =new Test1();
		t1.show();
		//当t为空字符串,输出0,当t不为空字符串输出大于0,当t为空对象(null),抛出NullPointerException错误
	}
	
	

}

数组是引用类型

package com.lx.chapter3;

public class Test3 {

	public  static void change(int[]  arrs)
	{
		arrs[0] =100;
		
	}
	
	public static void main(String[] args) {
		
		int[]  arr = {1,2,3,4,5};
		
		System.out.println(arr[0]);
		
		change(arr);
		
		System.out.println(arr[0]);
		
	}

}

package com.lx.chapter3;

public class Test4 {
	
	public static void main(String[] args) {
		
		//java数组是一个固定长度的类型一致的数据结构。
		int[]  arrs = {3,4,6};
		arrs[3] =100;
		System.out.println(	arrs[3]);
	}

}

  1. 编写源码 .java文件

2. 编译期间(javac):编译能够通过 java文件编译成.class文件,编译时错误(不能生成.class)

3. 运行期间(java):运行.class 文件,java虚拟机可执行文件, 可以通过或抛出异常(不指上面的这个例子,生成.class,可能会发生运行时错误。