Java笔记(一)基础、流程控制、数组、面向对象基础

堆(Heap) :此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。
栈(Stack) :是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不等同于对象本身,是对象在堆内存的首地址)。 方法执行完,自动释放。
方法区(Method Area) :用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

基础

public class test {
    public static void main(String[] args){
        System.out.println("hello world");
    }
}

 关键字

【基础篇】Java关键字(超详细)-CSDN博客

package

java中文件的大小分配:project--> module --> package -->class

这个关键字放置在class的顶部,用于声明这个class属于哪个package

package 顶层包名.子包名 ;

JDK中主要的包介绍:
java.lang ----包含一些Java语言的核心类,如String、Math、Integer、 System和Thread,提供常用功能
java.net ----包含执行与网络相关的操作的类和接口。

java.io ----包含能提供多种输入/输出功能的类。

java.util ----包含一些实用工具类,如定义系统特性、接口的集合框架类、使用与日期日历相关的函数。

java.text ----包含了一些java格式化相关的类

java.sql ----包含了java进行JDBC数据库编程的相关类/接口

java.awt ----包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。

import(导入)
为了使用定义在其它包中的Java类,需用import语句来显式引入指定包下所需要的类

  •  import语句,声明在包的声明和类的声明之间。
  • 如果需要导入多个类或接口,那么就并列显式多个import语句即可
  • 如果使用a.* 导入结构,表示可以导入a包下的所有的结构。举例:可以使用java.util.*的方式,一次性导入util包下所有的类或接口。
  • 如果导入的类或接口是java.lang包下的,或者是当前包下的,则可以省略此import语句。
  • 如果已经导入java.a包下的类,那么如果需要使用a包的子包下的类的话,仍然需要导入。
  • 如果在代码中使用不同包下的同名的类,那么就需要使用类的全类名的方式指明调用的是哪个类。
  • (了解) import static 组合的使用:调用指定类或接口下的静态的属性或方法

数据类型

数据类型 变量名=值

数据类型:

声明long时需要在最后加L或l,float要加f或F

long a=100000L
float b = 0.2f

 类型转换--自动类型提升(小->大)

1、byte->short->int->long->float->double,按照表示数字的范围排序,小的可以转换为大的。例如 下面这种是合理的,但是反过来不行

byte a = 2; int c ;c = a //ok
byte a ; int c=2 ;a = c //no

2、在运算中,会符合运输数中最 大 的那个数据类型:

double a=7;int b=3;int c = a+b; //no
long a=7;int b=3;double c = a+b; //ok

3、byte,short,char做运算,结果都为int(从char到int会转换为字符的ascll码)

byte a=1;short b=3; short c=a+b//no,a+b的结果已经转换为了int

4、下面这个,123是int类型,转换为了long,所以不写123L也不会报错

long a = 123

5、未定义的数字,整数默认为int,小数默认为double

 类型转换--强制转换(大->小)

        int a = (int) 123.22;
        System.out.println(a); //123

字符串

        String a = "i love you";
        int b =3;
        short c = 4;
        boolean d = false;
        String e = c+b+a+d;

        System.out.println(a); //i love you
        System.out.println(a+b); //i love you3
        System.out.println(e); //7i love youfalse

强转数据类型不可行

        String a = "10";
        int b =(int) a;//no

运算符

++ ,--不改变数据的类型

        short a = 1;short b=++a;//合理,不等价于 short a = 1;short b=a+1(无法运行);

 同理,赋值运算符也不改变数据的类型

&&只要有一个条件不一样就是不满足,如果第一个条件就是不满足就不判断后面的条件。而&要对所有的条件都进行判断。

||和|都是表示“或”,区别是||只要满足第一个条件,后面的条件就不再判断,而|要对所有的条件进行判断。

三元运算符

int a = (3>1)?2:3;

流程控制

if..else:

if (条件表达式1) {
  	语句块1;
} else if (条件表达式2) {
  	语句块2;
}
...
}else if (条件表达式n) {
 	语句块n;
} else {
  	语句块n+1;
}

从键盘获取输入

import java.util.Scanner;
public class test {
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        String name = scan.next();

        System.out.println("my name is "+name);
    }
}

 也可以指定获取的数据类型,例如

        int age = scan.nextInt();
        double salary = scan.nextDouble()

Switch case

switch(表达式){
    case 常量值1:
        语句块1;
        //break;
    case 常量值2:
        语句块2;
        //break; 
    // ...
   [default:
        语句块n+1;
        break;
   ]
}

按照顺序执行,出发遇到break,例如

        int num = 1;
        switch(num){
            case 0:
                System.out.println("zero");
            case 1:
                System.out.println("one");
            case 2:
                System.out.println("two");
            case 3:
                System.out.println("three");
            default:
                System.out.println("other");
                //输出one two three other

所以每个case都需要带break

        switch(num){
            case 0:
                System.out.println("zero");
                break;
            case 1:
                System.out.println("one");
                break;
            case 2:
                System.out.println("two");
                break;
            case 3:
                System.out.println("three");
                break;
            default:
                System.out.println("other");}

也可以在case处实现 或  的写法:

        switch(num){
            case 0:
            case 1:
                System.out.println("zero or one");
                break;
            case 2:
            case 3:
                System.out.println("two or three");
                break;
            default:
                System.out.println("other");
        }

for循环

for (①初始化部分; ②循环条件部分; ④迭代部分){
         	③循环体部分;
}
    for(int i=0;i<10;i++){
        System.out.println(i);
    }

while

①初始化部分
while(②循环条件部分){
    ③循环体部分;
    ④迭代部分;
}
        int i=0;
        while(i<10){
            System.out.println(i);
            i++;
        }

do-while循环

①初始化部分;
do{
	③循环体部分
	④迭代部分
}while(②循环条件部分); //满足条件才继续循环
        int i = 0;
        do{
            i++;
            System.out.println(i);
        }while(i<=20);

最简单"无限"循环格式,需要搭配break 

while(true) , for(;;), for(;true;)

break和continue

用于跳出循环和进入下一次循环

在多层循环嵌套中,可以使用label指定跳出的循环,例如:

class BreakContinueTest2 {
	public static void main(String[] args) {
		lable:for(int i = 1;i <= 4;i++){
		
			for(int j = 1;j <= 10;j++){
				if(j % 4 == 0){
					//break l;
					continue lable;
				}
				System.out.print(j);
			}
			System.out.println();
		}
	}
}

数组

单层数组

初始化和定义:

double[] salary = new double[]{1.1,2.2,3.3,4.4};
String[] name = new String[]{"lmx","lby","lll"};
int[] day = {1,2,3};
int[] age = new int[6];

元素调用

System.out.println(salary[2]);

赋值

salary[2] = 7;

数组的长度

System.out.println(salary.length);

多维数组

定义

        int[][] ifo1 = new int[][]{{2,3},{1,2},{3,4}};
        int[][] ifo2 = {{2,3},{1,2},{3,4}};
        String[][] if3 = new String[3][4];

动态定义:

        String[][] if3 = new String[3][];
        if3[0] = new String[]{"lmx","lby"};
        if3[1] = new String[]{"lmx1","lby","ppp"};

 调用

System.out.println(ifo2[1][1]);

默认值,不同的数组类型的默认值是不一样的:

        int[][] ifo1 = new int[1][1];
        String[][] ifo2 = new String[1][1];
        boolean[][] ifo3 = new boolean[1][1];

        System.out.println(ifo1[0][0]); //0
        System.out.println(ifo2[0][0]); //null
        System.out.println(ifo3[0][0]); //false

常用方法 

 Arrays.toString 转为字符串

System.out.println(Arrays.toString(ifo1));

Arrays.equals 数组比较 

System.out.println(Arrays.equals(ifo2,ifo1));

 Arrays.fill 替换全部

        int[] ifo2 = new int[10];
        Arrays.fill(ifo2,10);
        System.out.println(Arrays.toString(ifo2));
//[10, 10, 10, 10, 10, 10, 10, 10, 10, 10]

 Arrays.sort 排序

        Arrays.sort(ifo1);
        System.out.println(Arrays.toString(ifo1));

二分查找

Arrays.binarySearch(ifo1,12)

面向对象

基础

 定义类:

public class person {
    int age;
    String name;
    public void say(String str){
        System.out.println(str);
    }

    public void say_age(){
        System.out.println(age);
    }
    
}

创造对象,调用对象:

        person p1 = new person();
        p1.name="lmx";
        p1.age = 22;
        p1.say("ggggg");
        p1.say_age();

成员变量 vs 局部变量

二者区别:

1、声明位置和方式 (1)实例变量:在类中方法外 (2)局部变量:在方法体{}中或方法的形参列表、代码块中
2、在内存中存储的位置不同 (1)实例变量:堆 (2)局部变量:栈
3、生命周期 (1)实例变量:和对象的生命周期一样,随着对象的创建而存在,随着对象被GC回收而消亡, 而且每一个对象的实例变量是独立的。 (2)局部变量:和方法调用的生命周期一样,每一次方法被调用而在存在,随着方法执行的结束而消亡, 而且每一次方法调用都是独立。
4、作用域 (1)实例变量:通过对象就可以使用,本类中直接调用,其他类中“对象.实例变量” (2)局部变量:出了作用域就不能使用
5、修饰符(后面来讲) (1)实例变量:public,protected,private,final,volatile,transient等 (2)局部变量:final
6、默认值 (1)实例变量:有默认值 (2)局部变量:没有,必须手动初始化。其中的形参比较特殊,靠实参给它初始化。

 

方法

Java里的方法不能独立存在,所有的方法必须定义在类里。

方法中可以调用类中的方法或属性,不可以在方法内部定义方法

[修饰符] 返回值类型 方法名([形参列表])[throws 异常列表]{
方法体的功能代码
}

修饰符:可选的。方法的修饰符也有很多,例如:public、protected、private、static、abstract、native、final、synchronized等。
        其中,权限修饰符有public、protected、private。在讲封装性之前,我们先默认使用pulbic修
饰方法。
        其中,根据是否有static,可以将方法分为静态方法和非静态方法。其中静态方法又称为类方法,非静态方法又称为实例方法。


返回值类型: 表示方法运行的结果的数据类型,方法执行后将结果返回到调用者。

        无返回值,则声明:void
        有返回值,则声明出返回值类型(可以是任意类型)。与方法体中“ return 返回值”搭配使用

public int getIntBetweenOneToHundred(){
return (int)(Math.random()*100+1);
}

 对象数组

数组的元素可以是基本数据类型,也可以是引用数据类型。当元素是引用类型中的类时,我们称为对象数组。

也就是说,数组中包含的都是类的对象,例如:

String[],person[],Student[]

方法重载

方法重载:在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可。
参数列表不同,意味着参数个数或参数类型的不同
重载的特点:与修饰符、返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。
重载方法调用:JVM通过方法的参数列表,调用匹配的方法。
先找个数、类型最匹配的再找个数和类型可以兼容的,如果同时多个方法可以兼容将会报错

public class person {
    int number,state,score;
    static void say(int x){
        System.out.println("one");
        System.out.println(x);
    }
    static void say(String name){
        System.out.println("two");
        System.out.println(name);
    }
}

可变个数的形参

即当定义一个方法时,形参的类型可以确定,但是形参的个数不确定,那么可以考虑使用可变个数的形参。

1. 可变个数形参的方法与同名的方法之间,彼此构成重载
2. 可变参数方法的使用与方法参数部分使用数组是一致的,二者不能同时声明,否则报错。

3. 当有多个重载方法,调用形参最像的那个
4. 方法的参数部分有可变形参,需要放在形参声明的最后
5. 在一个方法的形参中,最多只能声明一个可变个数的形参

2. 可变参数方法的使用与方法参数部分使用数组是一致的,二者不能同时声明,否则报错:

    public static void print(int[] nums){
        System.out.println(nums[0]);
    }

    public static void print(int...nums){
        System.out.println("@2222");
    }

上面两种方法都能定义可变形参,但是两者是不能同时定义的,认为其形参一样

 但是二者的调用方法是有区别的,两者方法都可以使用下面这种调用

print(new int[]{1,2,3});

 但是下面这种调用只适合 int...nums 这种形参的:

print(1,2,3);

 3. 当有多个重载方法,调用形参最像的那个


public class Main {
    public static void main(String[] args) {
        print(1); //2222

    }
    public static void print(int...nums){
        System.out.println(nums[0]);
    }

    public static void print(int i){
        System.out.println("2222");
    }
}

封装性

java内部设置了四种修饰符:

 规则:

外部类:public、缺省

成员变量、成员方法、构造器、成员内部类:public、protected、缺省、private

 构造器

我们能不能在new对象时,直接为当前对象的某个或所有成员变量直接赋值呢? 可以,Java给我们提供了 构造器(Constructor) ,也称为 构造方法。

[修饰符] class 类名{
 [修饰符] 构造器名(){
 // 实例初始化代码
}
 [修饰符] 构造器名(参数列表){
 // 实例初始化代码
}
 }

1. 构造器名必须与它所在的类名必须相同

2. 它没有返回值,所以不需要返回值类型,也不需要void。

3. 构造器的修饰符只能是权限修饰符,不能被其他任何修饰。比如,不能被static、final、 synchronized、abstract、native修饰,不能有return语句返回值。

public class Main {
    public static void main(String[] args) {

        person p1 = new person();
        p1.say();
        person p2 = new person("lll",30);
        p2.say();
    }
}

class person{
    private String name;
    private int age ;
    
    public person(){
        name = "lmx";age = 20;
    }

    public person(String n,int a){
        name = n;
        age = a;
    }

    void say(){
        System.out.println(name);
        System.out.println(age);
    }

}

一个类中可以有多个构造器,彼此形成重载

可以给类的属性赋值的过程:

① 默认初始化

② 显式初始化

③ 构造器中初始化

④ 通过"对象.属性"或"对象.方法"的方式,给属性赋值

顺序:

1-2-3-4

JavaBean 

JJavaBean是一种Java语言写成的可重用组件。是指符合如下标准的Java类:

  • 类是公共的
  • 有一个无参的公共的构造器
  • 有属性,且有对应的get、set方法

例如

class person{
    private String name;
    private int age ;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

this

当形参与成员变量同名时,如果在方法内或构造器内需要使用成员变量,必须添加this来表明该变量是类的成员变量。

 可以使用this调用对象的属性和方法:

class Person{		// 定义Person类
	private String name ;	
	private int age ;			
	public Person(String name,int age){	
		this.name = name ;   
		this.age = age ;  
    }
    public void setName(String name){
        this.name = name;
    }
    public void setAge(int age){
        this.age = age;
    }
	public void getInfo(){	
		System.out.println("姓名:" + name) ;
		this.speak();
	}
	public void speak(){
		System.out.println(“年龄:” + this.age);	
	}
}

也可以调用构造器,

  • this():调用本类的无参构造器
  • this(实参列表):调用本类的有参构造器
public class Student {
    private String name;
    private int age;

    // 无参构造
    public Student() {
//        this("",18);//调用本类有参构造器
    }

    // 有参构造
    public Student(String name) {
        this();//调用本类无参构造器
        this.name = name;
    }
    // 有参构造
    public Student(String name,int age){
        this(name);//调用本类中有一个String参数的构造器
        this.age = age;
    }

   
}

继承

[修饰符] class 类A {
	...
}

[修饰符] class 类B extends 类A {
	...
}
class person{
    int age = 20;
    public void say(){
        System.out.println("lllll");
    }
}

class student extends person{
    public void get_age(){
        System.out.println(this.age);
        this.say();
    }

}

1、子类会继承父类所有的实例变量和实例方法

        但是由于封装的原因,子类可能不能直接调用某些父类的属性和方法,子类可以重新声明父类的属性和方法,相当于重写

2、顶层父类是Object类。所有的类默认继承Object,作为父类。

        可以使用s1.getClass().getSuperclass()获取父类

3、Java只支持单继承,不支持多重继承(java的单继承性)

方法重写

  1. 子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表

  2. 如果父类的方法返回值是基本数据类型,则子类的必须一样。如果父类方法的返回值是引用数据类型(例如类),则子类方法返回值不能比其大(例如不能是这个类的父类)

  3. 只有方法才能重写覆盖,属性是无法重写覆盖的

super 

  • super可用于访问父类中定义的属性
  • super可用于调用父类中定义的成员方法
  • super可用于在子类构造器中调用父类的构造器

注意事项: 

  • 尤其当子父类出现同名成员时,可以用super表明调用的是父类中的成员
  • super的追溯不仅限于直接父类
  • super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识
class person{
    int age = 0;
    public void say(){
        System.out.println("aaa");
    }
}

class student extends person{
    int age = 22;
     public void say(){
         System.out.println("bbb");
     }
     public void test(){
         this.say(); //bbb
         super.say(); //aaa
         System.out.println(this.age);//22
         System.out.println(super.age); //0
     }
}

 super调用构造器

子类继承父类时,不会继承父类的构造器。只能通过“super(形参列表)”的方式调用父类指定的构造器。

规定:“super(形参列表)”,必须声明在构造器的首行。

在构造器的首行可以使用"this(形参列表)",调用本类中重载的构造器,结合②,结论:在构造器的首行,"this(形参列表)" 和 "super(形参列表)"只能二选一。

如果在子类构造器的首行既没有显示调用"this(形参列表)",也没有显式调用"super(形参列表)",则子类此构造器默认调用"super()",即调用父类中空参的构造器。

由③和④得到结论:子类的任何一个构造器中,要么会调用本类中重载的构造器,要么会调用父类的构造器。只能是这两种情况之一。

由⑤得到:一个类中声明有n个构造器,最多有n-1个构造器中使用了"this(形参列表)",则剩下的那个一定使用"super(形参列表)"。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值