Java 学习1.0——变量、运算符、循环、数组、类和对象

JJJJJavaaaaaaaa啊啊啊啊

Chapter1

  1. JDK = JRE + java开发工具, JRE = JVM +核心类库

  2. 运行的本质就是把.class 装载到JVM虚拟机中执行

  3. 对于类和方法的注释 要以javadoc 的方式来写/** */

  4. dos命令:dir查看里面的文件cd切换目录tree查看所有子目录cls清屏md创建文件rd删除目录del删除文件move 剪切copy 拷贝

Chapter2 变量

  1. 变量相当于内存中一个数据存储空间的表示——变量的声明,赋值,使用

  2. +两边有一边是字符串,那么就做拼接运算。如果两边都是数值就做求和运算。

  3. Java数据类型:
    1️⃣ 基本数据类型:数值型:整数类型——存放整数:byte[1] short[2] int[4] long[8]
    浮点类型——存放小数:float[4] double[8]
    字符型——存放单个字符:char[2]
    布尔型——存放true、false:boolean[1]
    2️⃣ 引用数据类型:类(class),接口(interface),数组([ ])

  4. java自动类型转化(在进行赋值或者运算时,精度小的 自动提升至 精度大的):

    • char → int → long → float → double

    • byte → short → int → long → float → double

    • boolean类型不参与类型的自动转化

    • 有多种数据类型一起运算的时候,系统会把他们都转化到精度最高的类型;

    • (byte, short) 和 char 之间不会相互自动转化;

    • byte, short 和 char 三者可以计算,也就是说只有有这三个任何一个在计算的时候,都会会首先自动转化为int类型;

    • float d1 = 2 + 2.2;  
      // 错误,因为2是默认的int,2.2是默认的double,转化为double计算后不能赋给float
      int d2 = 1.1;
      // 错误,double不能转int
      byte d3 = 10;
      int n2 = 1;
      byte b2 = n2;
      // 错误:d3是byte一个字节,n2是int四个字节,于是不能把n2赋给b2
      byte m1 = 10;
      char m2 = m1;
      short m3 = m1;
      // 错误: (byte, short) 和 char 之间不会相互自动转化
      byte q1 = 10;
      byte q2 = 10;
      byte q3 = q1 + q2;
      // 错误:byte参加运算,会自动转化为int类型,所以不正确
      
  5. 基本数据类型转化为字符串String ——+ ""

    int n1 = 100;
    float f1 = 1.1F;
    double d1 = 4.5;
    boolean b1 = true;
    
    String s1 = n1 + "";
    String s2 = f1 + "";
    String s3 = d1 + "";
    String s4 = b1 + "";
    

    字符串String转化为对应的基本数据类型——通过基本类型的包装类调用parseXX方法

    // 使用基本数据类型对应的包装类的相应方法 得到基本数据类型
    String s5 = "123";
    int num1 = Integer.parseInt(s5);
    double num2 = Double.parseDouble(s5);
    float num3 = Float.parseFloat(s5);
    long num4 = Long.parseLong(s5);
    short num5 = Short.parseShort(s5);
    byte num6 = Byte.parseByte(s5);
    boolean num7 = Boolean.parseBoolean("char");
    
    // 取出来s5字符串的第一个字符
    System.out.println(s5.charAt(0));
    
  6. java的整型常量默认为int类型,声明long类型常量后需加L或者l
    java的浮点型常量默认为double类型,声明float类型常量后需加F或者f

  7. 浮点数 = 符号位+指数位+尾数位

  8. char的本质是一个整数,可以参与运算,在输出的时候是unicode码对应的字符
    char c1 = 'a'输出【a】
    char c3 = 97输出【a】

字符型存储到计算机的时候,‘a’ >> 码值97 >> 二进制1100001 >> 存储
字符型从计算机读取的时候,二进制 >> 97 >> ‘a’ >> 显示

char m1 = 'a';
char m2 = 'z';
System.out.println(m1 + m2); //char类型本质是整数运算 >>> 输出219
  1. ASCII码表:使用1个字节,有128个字符的编码(没用完);
    Unicode码: 使用了2个字节,英文和汉字都占2个字节;
    UTF-8:是最广泛使用的一种Unicode实现方式,变长编码,且字母1个字节,汉字3个字节。

  2. 布尔类型:boolean,但是java中不可以用0或者非零表示true和false

  3. pirntln、print的运算规则:在遇到第一个字符串之前,所有的数遇到加号即相加。当遇到任意字符后,加号就变成了字符串的拼接。

Chapter3 运算符

  1. 在java中 取模 % 的本质: a % b = a - a / b * b,如果a是小数则:a % b = a - (int)a / b * b

  2. ++的独立使用:i++ <=> ++i <=> i = i+1
    ++作为表达式使用:[1] 前++:++i先自增再操作 ; [2] 后++:i++先操作后自增

    int j = 8;
    int k = ++j; // 等价于 j=j+1, k=j
    int m = j++; // 等价于 m=j, j=j+1
    
    int i = 1; // i->1
    i = i++;  //(1)temp=i (2)i++ (3)i=temp  所以最后i=1
    
    int i = 1; // i->1
    i = ++i;  //(1)i++ (2)temp=i (3)i=temp  所以最后i=2
    
  3. 关系运算符: == != < > <= >= instanceof 关系表达式的运算的结果是boolean型

  4. 逻辑运算符:短路与&& 短路或|| 取反! 逻辑与& 逻辑或| 逻辑异或^

    • 短路与&&:如果第一个为false,则后面的条件不会判断,最终直接为false【效率高】
    • 逻辑与&:如果第一个为false,后面的条件仍然会执行和判断
    • 短路或||:如果第一个为true,则后面的条件不会判断,最终直接为true【效率高】
    • 逻辑或|:如果第一个为true,后面的条件仍然会执行和判断
  5. 赋值运算符:复合赋值运算符底层会进行类型转化

    byte b = 2;
    b += 2;   // √ 等价于b = (byte)(b+2)
    b = b + 2 // × b+2会变成int类型,int类型无法赋值给byte类型
    
  6. 三元运算符:条件表达式?表达式1:表达式2;——如果条件表达式为真,则运算后结果为表达式1,否则为2。

    //寻找两数之间最大数
    int m = 59;
    int n = 2;
    int max = m > n ? m : n;
    System.out.println(max);
    
  7. 标识符命名规则:由字母,$,_,数字组成;不以数字开头;不可以是关键字保留字,区分大小写,不含空格。

  8. 标识符命名规范:驼峰法xxxYyyZz,常量名:XXX_YYY_ZZZ,类名接口名:XxxYyyZzz

  9. 键盘输入:

    import java.util.Scanner; // 把java.util包下的Scanner类导入
    public class Input{
    	public static void main(String[] args){
    		// Scanner 类表示简单的文本扫描器,在java.util 包
    		// 1.引入 Scanner类所在的包
    		// 2.创建Scanner对象 new创建一个对象
    		Scanner myScanner = new Scanner(System.in);
    		//3. 接受用户的输入,使用相关的方法
    		System.out.println("请输入名字:");
    		String name = myScanner.next();
    
    		// 几种格式的键盘输入读取
    		String name = myScanner.next();
            int a =  myScanner.nextInt();
            double b =  myScanner.nextDouble();
            char c =  myScanner.next().charAt(0);
    
  10. 位运算

    1. 对于有符号数来讲,最高位0表示正数,1表示负数。
    2. 正数的原码、反码、补码都一样。
    3. 负数的反码:原码的符号位不变,其他位按位取反。
    4. 负数的补码:其反码+1,同理负数的反码 = 负数的补码 -1。
    5. 0的反码补码都是0。
    6. java没有无符号数,所有数都有符号。
    7. 计算机运算的时候,都是以补码的方式运算的。看运算结果的时候,看的是原码。
  11. 位运算符:按位与&按位或|按位异或^按位取反~

    1. 算数左移<<:符号位不变,低位补0;
    2. 算数右移>>:符号位不变,低位溢出,并用符号位补溢出的高位;
    3. 无符号右移>>>:低位溢出,高位补0。

Chapter4 程序控制结构

1)if-else

if(age > 18){
			System.out.println("1");
}else if{
    System.out.println("2");
}else{
    System.out.println("3");
}
// 如果没有else 有可能程序就一个入口都没有哦

2)switch

// 表达式的数据类型,应该和case后面的常量类型一致
// 或者可以自动转化成可以相互比较的类型
// 表达式的返回值必须是:byte short int char enum[枚举] String!!!
switch(表达式){ 
			case1:  
				System.out.println("今天周一");
				break;   //如果不加break就会继续向后执行
			case2:
				System.out.println("今天周二");
				break;
			case3:
				System.out.println("今天周三");
				break;
			default:
				System.out.println("未知");	
		}

// 利用穿透 
switch(score){
			case 3:
			case 4:
			case 5:
				System.out.println("春天");
        		break;
    		default:
        		System.out.println("春天");
}
  1. 表达式的数据类型应该和case后面的常量类型一致, 或者可以自动转化成可以相互比较的类型;
  2. 表达式的返回值必须是:byte, short,int, char, enum[枚举], String;
  3. case子句中的值必须是常量或者是常量表达式(比如’a’,1,‘a’+1…),而不能是变量;
  4. default:子句是可选的,没有匹配的case就执行default,但是没有default也可以;
  5. break语句:作用就是跳出switch语句,如果没有break程序就顺序执行其他case;

3)for循环

for(①循环变量初始化;②循环条件;④循环变量迭代){
    ③循环操作(可以是多条语句)
}
// 写法一
for(int i = 1; i < 10; i++){
    System.out.println("a");
}

// 写法二[分号不能少]
int i = 1;  //循环变量的初始化
for( ; i < 10; ){
    System.out.println("a");
    i++; //循环变量迭代
}

// 无限循环
for(;;){
    
}

4)while循环

循环变量的初始化;
while(循环条件){
	循环体(语句);
	循环变量迭代;
}

无限循环(用break退出):

while(true){
	if(XXX){break;}
}

5)do - while循环

先执行在判断,至少会执行一次

循环变量的初始化;
do{
    循环体(语句);
    循环变量迭代;
}while(循环条件);  //记得分号;

6)break

  1. 用于终止某个语句块的执行;
  2. break语句块出现在多层嵌套语句块中的时候,可以通过标签指明要终止的是哪一层的语句块,break 标签名。如果没有label,则break默认退出最近的循环体。

7)continue

  1. 用于结束本次循环,继续执行下一次循环;
  2. continue语句块出现在多层嵌套语句块中的时候,可以通过标签指明要跳过的是哪一层的循环,continue 标签名(label)。如果没有label,则continue默认退出最近的循环体。

8)return 跳转控制语句

  1. 用于跳出所在的方法,若用在main方法,则退出程序。

Chapter5

1)数组

可以存放多个同一类型的数据,数组属于引用类型这一数据类型。

  1. 注意事项

    • 数组中的元素可以是任何数据类型,但是不能混用。

    • 数组创建后,如果没有赋值,则默认值为:int 0, short 0, long 0, byte 0, float 0.0, double 0.0, char \u0000, boolean false, String null。

    • 数组的下标必须在指定范围内使用,否则运行时报越界异常。

    • 数组是引用类型,所以数组型数据是对象(object)。

    • 数组赋的值是【地址】,赋值的方式是引用传递。基本数据类型赋值是值传递,拷贝值。

      // 把arr1赋给arr2,改变arr2,arr1也会改变【数组赋值是引用赋值,不是值传递】
      int arr1[] = {1,2,3};
      int arr2[] = arr1;
      

      arr1,arr2中存放的是地址,对应堆的地址里面有一定个数的空间。

    • 若原来的数据空间没有变量引用,就会被JVM当做垃圾回收。

  2. 数组的定义:

    //第一种动态分配方式
    int array[] = new int[5]; // 创建一个数组,名字为a,存放5个int
    
    //第二种动态分配方式
    int array[]; // 先声明数组,此时a是null
    array = new int[5]; // 分配内存空间,可以存放数据
    
    //静态初始化
    int array[] = {1, 2, 3, 4, 5};   // 创建并初始化一个数组
    
  3. 数组的访问:

    array[i]
    
  4. 数组的长度:

    array.length
    
  5. 数组拷贝(要求两个数组的空间是独立的,因为数组形如arr1 = arr2的赋值的方式是引用传递【传递地址】)

    int array1[] = {1,2,4,5};
    
    // 开辟一个新的空间 这个空间的地址肯定和array1不一样,这个空间里的每一个元素为初始化的0
    int array2[] = new int[array1.length];
    
    // 遍历array1 拷贝每一个值到array2
    for(int i = 0; i < array1.length; i++){
        array2[i] = array1[i];
    }
    
  6. 数组添加元素(本质是数组的扩容)

  7. 二维数组

    int array[][] = new int[2][3]; // 动态初始化方式1
    
    int array[][];
    array = new int[2][3]; // 动态初始化方式2
    
    int array[][] = {{0,1,2,3},{4,5,6,7},{8,9,9,9},{6,6,6,6}}; // 静态初始化
    int array[][] = {{1,2,3},{0},{1,6}}; // 静态初始化
        
    二维数组中的一维数组个数(即行数):array.length
    每个一维数组的长度(即列数):array[i].length
    访问每一个元素 array[i][j]
    

    二维数组 栈指向堆中的一个空间,这个空间里的元素是一维数组的地址,指向另一个空间,这个空间才存放元素

    动态初始化:列数不确定的情况:

    打印:
    1
    2 2
    3 3 3
    4 4 4 4
    
    // 创还二维数组,包含4个一维数组,但是每个一维数组还没有开数据空间!!!! 
    int array[][] = new int[4][];
    for(int i =0; i < array.length; i++){
        // ☆遍历二维数组array的每个一维数组,给每个一维数组开空间!!这里如果没给一维数组new,那么array[i]就是null
        array[i] = new int[i+1];
        //遍历一维数组,并给一维数组的每个元素赋值
        for(int j =0; j < array[i].length; j++){
            array[i][j] = i+1;
        }
    }
    
    // 遍历输出
    for(int i = 0; i < array.length; i++){
        for(int j = 0; j < array[i].length; j++){
            System.out.print(array[i][j]);
        }System.out.println("");
    }
    

    其他的一些小tips:

    int[] x, y[];  // 声明一个一维数组x,一个二维数组y
    int array[] = new int[]{1,2,4}; // 这种写法也可以哦,由编译器自动判断空间多大
    

2)排序

2.1 冒泡排序

通过对待排序的序列,依次两两比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前向后移。

从小到大排序 》》》大的后移
从大到小排序 》》》 小的后移

// 从小到大排序
// 24 69 80 57 13
// 24 69 57 13 80
// 24 57 13 69 80
// 24 13 57 69 80
int array[] = {24,69,80,57,13};
int temp = 0;
for(int i = 0; i < array.length - 1; i++){
    for(int j = 0; j < array.length - i - 1; j++){
    if(array[j] > array[j+1]){  // 从小到大排序就是> ,从大到小排序空间就是<,so easy
        temp = array[j];
        array[j] = array[j+1];
        array[j+1] = temp;
        } 
    }	
}
2.2 查找
2.2.1 顺序查找
for(int i = 0; i < array.length; i++){
	if(array[i] == num){
        System.out.println(i)
    }
}
2.2.2 二分查找

Chapter6 OOP类和对象(class and object)

  1. int是一种数据类型,类是自定义的数据类型,可以通过类创建多个对象(也就是类的实例化)。

  2. 类是抽象的,概念的,代表一类事物,是数据类型;

  3. 对象是具体的,实际的,代表一个具体的实物,是实例;

  4. 类是对象的模板,对象是类的一个个体,对应一个实例。

  5. 实际操作

    public class object01{
    	public static void main(String[] args){
    
    		// 实例化一只猫(创建一只猫对象)
    		// new Cat() :创建一只猫对象
    		// Cat cat1 = new Cat() :把创建好的猫赋给cat1
    		Cat cat1 = new Cat();
    		cat.name = "小白";
    		cat.age = 12;
    		cat.color = "白色";
            
    		// 创建第二只猫,并赋给cat2
    		Cat cat2 = new Cat();
    		cat.name = "小蓝";
    		cat.age = 11;
    		cat.color = "黑色";
    		
            // 访问对象的属性
            System.out.println("第1只猫的信息" + cat1.name + " " + cat1.age + " " + cat1.color);
    		System.out.println("第2只猫的信息" + cat2.name + " " + cat2.age + " " + cat2.color);
    
    	}
    }
    
    // 定义一个猫类Cat -> 自定义的数据类型
    class Cat{
    	//属性
    	String name;
    	int age;
    	String color;
    }
    
  6. 🔴对象的属性在内存中的存在形式:
    如果属性的类型是字符串,而字符串是引用类型,堆中对应的空间里就存放指向方法区常量池的地址,如果是基本数据类型就直接存在堆中。cat只是指向了对象的空间,叫做对象名(或者是对象引用),new Cat()创建的对象空间才是真正的对象,创建后里面默认值为null ,0, null,后三条语句"小白",12,”白色“才会根据数据类型分别赋值或者存地址进去。

6.1 创建对象
// 方法1 先声明再创建
Cat mycat;
mycat = new Cat();

// 方法2 直接创建
Cat mycat = new Cat();
6.2 类与对象的内存分配机制
  1. 栈:一般存放基本数据类型(局部变量)
  2. 堆:存放对象(就包括之前的Cat mycat ,数组)
  3. 方法区:常量池(常量,比如字符串),类加载信息
6.3 属性(又叫成员变量 field)
6.3.1 属性的定义

属性是类的一个组成部分,一般是基本数据类型,也可以是引用类型(对象,数组)

  • 属性的定义:访问修饰符 属性类型 属性名

    • 访问修饰符 ——控制属性的访问范围:包括public, proctected, 默认, private

    • // 【属性的定义】
      class Person{
      	int  age;
      	String name;}
      
  • 属性的定义类型可以为任意类型,包含基本类型和引用类型;

  • 属性如果不赋值有默认值,规则和数组一致。

    • int 0, short 0, long 0, byte 0, float 0.0, double 0.0, char \u0000, boolean false, String null。
6.3.2 访问属性
// 对象名.属性名
mycat.color;
mycat.age;
6.4 成员方法的创建和调用(为了让类除了属性还有一些行为)
6.4.1 成员方法的定义
// 【成员方法的定义】
访问修饰符(有四种) 返回数据的类型 方法名(形参列表) {//方法体
	语句;
	return...;
}
6.4.2 成员方法举例
public class method{
	public static void main(String[] args){
		//【方法的调用】 创建一个对象,然后调用方法
		Person myperson = new Person();  //创建一个对象
		myperson.speak();				//调用speak方法
        
        int res = myperson.sum(2,3);	//调用sum方法 传参给num1,num2,
        System.out.println(res);	    //将方法sum返回的值赋给变量res
   
	}
}

class Person{
	int  age;  // 类的属性
	System name; // 类的属性
    
	// 【创建成员方法1】 添加speak成员方法 输出“我是一个好人”
	// public :表示方法是公开的
	// void :表示方法没有返回值
	// speak() :speak是方法名,( )是形参列表
	// {} :方法体,可以写我们要执行的代码
	public void speak(){
		System.out.println("我是一个好人");
	}
    
    // 【创建成员方法2】 返回两个值的和
    // int num1,int num2: 形参列表,表示当前有2个int类型的形参,可以接受用户的输入
    // int 表示return返回值为int类型
    public int sum(int num1, int num2){
		int res = num1 + num2;
        return res;
	}
    
}
【创建成员方法3——有多个返回值】 
public class method03{
	public static void main(String[] args){
		// 有两个返回值 返回一个和 一个差
		Work mywork = new Work();  //新建一个对象
		int arr[] = mywork.output(2,3); 
        //输入一个2,一个3,接受一个返回值,返回值是一个数组,里面有俩值 
		System.out.println("和为:" + arr[0]);
		System.out.println("差为:" + arr[1]);
	}
}

class Work{
	public int[] output(int num1, int num2){  //返回值是一个数组,数组里就可以包括多个返回值
		int array[] = new int[2]; // 创建一个新数组
		array[0] = num1 + num2;
		array[1] = num1 - num2;
		return array;
	}
}
6.4.3 成员方法注意细则:

🔴 ! 成员方法的调用机制0203_韩顺平Java_方法调用机制_哔哩哔哩_bilibili

​ **1.**当程序执行到方法的时候,就会开辟一个独立的空间(栈空间);
​ **2.**当一个方法执行完毕,或者执行到return语句的时候,就会返回,返回到调用方法的地方。
​ **3.**返回后继续执行下面的代码。
​ **4.**当main方法(栈)执行完毕后,整个程序退出

返回数据类型
1.一个方法最多有一个返回值 [若要返回多个结果——>返回数组 ] ;
2.返回类型可以为任意类型,包含基本类型或引用类型(数组,对象) ;
3.如果方法要求有返回数据类型,则方法体中最后的执行语句必须为 return 值,而且要求返回值类型必须和 return 的 值类型一致或兼容;
4.如果方法是 void,则方法体中可以没有 return 语句,或者 只写 return ;

形参列表
1.一个方法可以有0个参数,也可以有多个参数,中间用逗号隔开;
2.参数类型可以为任意类型,包含基本类型和引用类型;
3.调用带参数的方法时,要对应着参数列表传入相同类型,或者兼容类型的参数;
4.方法定义时的参数为形参,方法调用时传入的参数为实参,实参和形参的类型要一致或者兼容,个数和顺序必须要一致。

方法体
1.方法名遵循驼峰命名法,见名知义;
2.方法体里面写完成功能的具体语句
3.方法体里面不能再定义方法(方法不能嵌套定义)

方法调用的细节说明
1.同一个类中的方法调用——直接调用即可,不需要创建对象
2.跨类中的方法 A类调用B类的方法——需要创建B类对象,再通过对象名调用方法
3.跨类方法的调用和方法的访问修饰符有关【暂不涉及】

6.4.4 成员方法的传参机制

1.基本数据类型传递的是(值拷贝),所以形参的任何改变不影响实参。
2.引用数据类型传递的是地址,所以可以通过形参影响实参。(包括数组 对象)0211_韩顺平Java_方法传参机制2_哔哩哔哩_bilibili

6.4.5 克隆对象
public class MethodExercise03{
	public static void main(String[] args){
		Person myperson = new Person();
		myperson.name = "lmx";
		myperson.age = 123;

		MyTools mytool = new MyTools();
		Person mypersonnew = mytool.copyPerson(myperson);
		// myperson和mypersonnew 都是Person对象,但是是两个独立的对象,属性相同
        
        // 可以通过输出对象的hashCode来看对象是否是一样的.
		System.out.println(mypersonnew == myperson);
	}
}


class Person{
	int age;
	String name;
}

class MyTools{
	public Person copyPerson(Person p){
	//编写一个方法copyPerson,可以复制一个Person对象,返回复制的对象。
	//注意要求得到新对象和原来的对象是两个独立的对象,只是他们的属性相同
	//编写方法的思路
	//1)方法的返回类型 Person
	//2)方法的名字 copyPerson
	//3)方法的形参 (Person p)
	//4)方法体,创建一个新对象,并复制属性,返回即可
		Person pnew = new Person();
		pnew.age = p.age;
		pnew.name  = p.name;
		return pnew;
	}
}
6.4.6 方法递归调用(方法自己调用自己)

[1] 执行一个方法时,就创建一个新的受保护的独立空间(栈空间);
[2] 方法的局部变量是独立的,不会相互影响,比如n变量;
[3] 如果方法中使用的是引用类型变量(比如数组,对象),就会共享该引用类型的数据;
[4] 递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError,死龟了;
[5] 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。

八皇后?
6.4.8 方法重载 OverLoad

java允许同一个类中,多个同名方法存在,但要求形参列表不一致。
注意事项:
(1)方法名必须相同;
(2)形参列表必须不相同(形参类型,个数,顺序必须至少有一个不同和参数名无关);
(3)对返回类型无要求

举例

class MyCalculator{
	public int calculate(int n1, int n2){
		return n1+n2;
	}
	public double calculate(int n1, double n2){
		return n1+n2;
	}
	public double calculate(double n1, int n2){
		System.out.println("被调用");
		return n1+n2;
	}
	public int calculate(int n1, int n2, int n3){
		return n1+n2+n3;
	}
}
6.5 可变参数

java允许将一个类中多个同名同功能但是参数个数不同的方法 封装成一个方法

6.5.1 可变参数基本语法
访问修饰符 返回类型 方法名(数据类型...形参名){
	方法体	
}

int... : 表示接收的是可变参数,类型是int,即可以接受多个int
使用可变参数的时候可以当做数组来使用,比如可以用 形参名.length 返回传入的形参个数,求和等等

举例:

// 可变参数 可以计算两个数 三个数 四个数...的和
public class VarParameter01{
	public static void main(String[] args){
		HspMethod m = new HspMethod();
		System.out.println(m.sum(1,2,3,4));
	}
}
class HspMethod{
	public int sum(int...nums){ // 功能相同 参数个数不同 -> 使用可变参数优化 本质是数组
		int sum  =0;
		for(int i  = 0; i < nums.length; i++){
			sum += nums[i];
		}return sum;
	}
}
6.5.2 可变参数的注意事项
  1. 可变参数的实参可以为0个或者任意多个;
  2. 可变参数的实参可以直接为数组;
  3. 可变参数的本质就是数组;
  4. 可变参数可以和普通类型的参数一起放在形参列表,但是必须保证可变参数在最后
    eg:public int Sum(int a, double b, int...c);
  5. 一个形参列表中只能有一个可变参数!
6.6 作用域
  1. 在java编程中,主要的变量就是属性(成员变量)和局部变量。
  2. 我们说的局部变量一般是指在成员方法中定义的变量。
  3. java中作用域的分类:
    1. 全局变量:也就是属性,作用域为整个类体,可以被本类使用,也可以通过对象调用被其他类调用。
    2. 局部变量:也就是除了属性之外的其他变量,局部变量的作用域为定义它的代码块中!只能在本类中对应的方法中使用。
  4. 全局变量(属性)可以不赋值,直接使用,因为有默认值。局部变量必须赋值后才能使用,因为没有默认值。
  5. 局部变量和全局变量(属性)可以重名,访问时就近原则。
  6. 在同一个作用域中,比如在同一个成员方法中,两个局部变量不能重名。
  7. 全局变量(属性)的生命周期长,伴随对象的创建而创建,伴随对象的销毁而销毁;
    局部变量生命周期短,伴随着他的代码块的执行而创建,伴随着代码块的销毁而销毁(执行方法时 该方法的局部变量被创建,方法结束后被销毁)。
  8. 全局变量(属性)可以加修饰符:public, proctected, 默认, private
    局部变量 不可以加修饰符。
6.7 构造方法/构造器(constructor)

是类的一种特殊方法,在构造对象的时候,完成对新对象的初始化。

6.7.1 构造器基本语法
修饰符 方法名(形参列表){
	方法体
}

注意事项:

  • 构造器的修饰符可以默认;
  • 🅰️构造器没有返回值;
  • 🅰️构造器名和类名字必须一样;
  • 参数列表和成员方法一样的规则;
  • 🅰️在创建对象的时候,系统会自动调用该类的构造器 去完成对象的初始化,并不是创建对象
6.7.2 构造器举例
public class constructor01{
	public static void main(String[] args){
		//创建人类对象的时候直接指定他的年龄和姓名
		//当new一个对象的时候,通过构造器直接指定名字和年龄
		Human my = new Human(90, "lmx");
		System.out.println(my.age);
		System.out.println(my.name);
	}
}

class Human{
    // 定义属性
	int age;
	String name;

	// 【构造器】:在创建对象的时候,系统会自动调用该类的构造器 去完成对象属性的初始化
	// 构造器的名字和Human一样
	// 构造器没有返回值
	// (String pName, int pAge)是构造器的形参列表
	public Human( int pAge, String pName){
		name = pName;
		age = pAge;
	}
}
6.7.3 构造器注意事项
  • 构造器本身也算是一个方法,和方法重载一样,一个类可以定义多个不同的构造器,即构造器重载;

  • 如果没有定义构造器,则系统会自动给类生成一个默认无参构造器(默认构造器);

    public class constructor01{
    	public static void main(String[] args){
    		Dog mydog = new Dog(); //使用的是默认的无参构造器
    }
    
    class Dog {
    	// 默认无参构造器
        /*
    	Dog(){
    	
    	}
    	*/
    }
    

    🔴一旦定义了自己的构造器,默认的构造器就被覆盖,无法使用。除非显式的定义一下:Dog(){}

    public class constructor01{
    	public static void main(String[] args){
    		Dog mydog = new Dog(); //使用的是默认的无参构造器,如果有了自己的构造器这个就不能用了
    }
    
    class Dog {
    	// 一旦定义了自己的构造器,默认的构造器就被覆盖,无法使用
    	public Dog(String dname){
            //...
        }
        
        // 除非显式的定义一下无参构造器:Dog(){}
        Dog(){
    	
    	}
    
    }
    
    6.7.4 引入构造器之后的对象创建的流程分析

    对象真正在堆里,p本质上是对象的引用哦!
    对象中的空间首先是默认值初始化–之后是类属性的显式初始化–最后才是构造器初始化

🔺🔺步骤解释:

​ 首先,在方法区先加载Person类信息(Person.class),只会加载一次,加载类的属性和方法;
​ 第二步骤,new Person 的时候在堆里面创建一个空间,有一个地址;
​ 第三步骤,完成对象的初始化:
​ 1.创建时默认初始化 age =0,name = null,
​ 2.显式初始化(类属性) age = 90,name = null,
​ 3.最后构造器初始化 age =20,name = 小倩

​ 第四步骤,将对象在堆中的地址返回给p。

6.8 this关键字

哪个对象调用该方法,该方法中的this就代表哪个对象!!!

public class This01{
	public static void main(String[] args){
		Dog mydog = new Dog("xiaoming", 12);
		System.out.println(mydog.name);
		System.out.println(mydog.age);
	}
}

class Dog{
	int age;
	String name;

	// 希望把构造器的形参直接写成属性名 但是出现变量的作用域的问题:
	// 构造器的name是局部变量 而不是属性 ;构造器的age是局部变量 而不是属性
	// ————于是引入this关键字——区分:类的属性和局部变量
	public Dog(String name, int age){ //构造器

		// this.name就是当前对象的属性name
		this.name = name ;

		// this.age就是当前对象的属性age
		this.age = age ;
	}
}
6.8.1 this关键字注意事项
  1. this 关键字可以用来访问本类的属性、方法、构造器
  1. 访问类的属性:this 用于区分当前类的属性和局部变量 (见上面的例子)
  2. 访问成员方法的语法:this.方法名(参数列表)
  3. 访问构造器语法:this(参数列表); 注意只能在构造器中使用!(即只能在构造器中访问另外一个构造器, 必须放在第一 条语句)
  4. this 不能在类定义的外部使用,只能在类定义的方法中使用
6.9 一些题目例子(综合使用 &匿名对象)

1.对象的属性方法 以及构造器 以及this的综合使用

2.分析程序:

public class Test{

	int count = 9; // Test类的属性

	public void count1(){ // Test类的成员方法
		count = 10;
		System.out.println("count1 = " + count);
	}

	public void count2(){  // Test类的成员方法
		System.out.println("count1 = " + count++);
	}

	public static void main(String[] args){ //这是Test类的main方法  任何一个类都可以有main方法
	// 1.new Test() 是匿名对象(没有人引用他)
	// 2.new Test().count1():在堆中新建一个Test类的匿名对象后,随即调用count1(),打印count=10
    // 3.匿名对象特点:由于没人引用他,所以只能使用一次 使用后会被销毁。随后就被销毁
		new Test().count1();  
        
    // 4. 在堆中新建一个Test对象,在栈中t1指向他 堆中的count属性:count =9
    // 5. t1.count2(); t1对象调用count2,count++ 先打印输出再自增 
        yingyong 
		Test t1 = new Test();
		t1.count2(); //输出9 之后自增
		t1.count2(); //输出10 之后自增
	}

	}


// 输出:
// count1 = 10
// count1 = 9
// count1 = 10

其他

  1. Math.random() 返回double类型的[0.0,1.0]的随机数

    System.out.println(Math.random());
    
  2. 字符串比较是否相等

    String name = "啦啦啦";
    System.out.println("啦啦啦".equals(name)) // 可以避免空指针
    
  3. 求幂次

    Math.pow(2,3) // 2^3
    
  4. 三元运算符:条件表达式 ? 表达式1 : 表达式2

    return num%2==0 ? true: false;
    
  5. javap 可以对class文件提供的字节码进行反编译。

  6. hashCode()方法 返回对象的哈希码值 将对象的内部地址转化为一个整数 可以用来判断对象是否一样。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值