类相当于一个模板,对象就是根据模板创建出来的实体,类是抽象的一种数据类型,并不是真实具体存在的。类的属性:成员变量,成员方法,可以调用成员方法来让类进行一些操作。
例如:Scanner sc= new Scanner(System.in);
String str = sc.nextLine();
System.out.println("你输入了:"+str);
sc.close();
所有的对象,都需要通过new
关键字创建。变量类型又分为基本类型变量和引用类型变量。 引用类型变量代表的是一个对象,基本类型变量代表的是一个值。
创建的类文件名应与类名称一致。
成员变量也叫做成员属性。我们可以通过类创建的对象来访问和修改这些变量。
public class Test { int age; String name; } public static void main(String[] args) { Test test = new Test(); test.name = "枫叶潇潇"; System.out.println(test.name); }
方法是语句的集合,是为了完成某件事情而存在的。完成某件事情,可以有结果,也可以做了就做了,不返回结果。
定义一个主方法 :
public static void main(String[] args) { //Body }
定义法任意一个方法:
[返回值类型] 方法名称([参数]){ //方法体 return 结果; }
return
也能用来提前结束整个方法,无论此时程序执行到何处,无论return位于哪里,都会立即结束个方法!一个类中可以包含多个同名的方法,但是需要的形式参数不一样。
public class Test { int a(){ //原本的方法 return 1; } int a(int i){ //ok,形参不同 return i; } void a(byte i){ //ok,返回类型和形参都不同 } void a(){ //错误,仅返回值类型名称不同不能重载 } }
构造方法(构造器)没有返回值。
//反编译结果 package com.test; public class Test { public Test() { //即使你什么都不编写,也自带一个无参构造方法,只是默认是隐藏的 } }
我们可以手动指定有参构造,当遇到名称冲突时,需要用到this关键字
public class Student { String name; Student(String name){ //形参和类成员变量冲突了,Java会优先使用形式参数定义的变量! this.name = name; //通过this指代当前的对象属性,this就代表当前对象 } } //idea 右键快速生成!
注意:this只能用于指代当前对象的内容,因此,只有属于对象拥有的部分才可以使用this,也就是说,只能在类的成员方法中使用this,不能在静态方法中使用this关键字。
静态变量和静态方法是类具有的属性(后面还会提到静态类、静态代码块),也可以理解为是所有对象共享的内容。我们通过使用static关键字来声明一个变量或一个方法为静态的,一旦被声明为静态,那么通过这个类创建的所有对象,操作的都是同一个目标,也就是说,对象再多,也只有这一个静态的变量或方法。那么,一个对象改变了静态变量的值,那么其他的对象读取的就是被改变的值。
类并不是在一开始就全部加载好,而是在需要时才会去加载,会加载类的情况:
所有被标记为静态的内容,会在类刚加载的时候就分配,而不是在对象创建的时候分配,所以说静态内容一定会在第一个对象初始化之前完成加载。
定义和赋值是两个阶段,在定义时会使用默认值。定义出来之后,如果发现有赋值语句,再进行赋值,而这时,调用了静态方法,所以说会先去加载静态方法,静态方法调用时拿到a,而a这时仅仅是刚定义,所以说还是初始值,最后得到0。
public class Student { static int a = test(); static int test(){ return a; } public static void main(String[] args) { System.out.println(Student.a); } }
代码块在对象创建时执行,也是属于类的内容,但是它在构造方法执行之前执行,且每创建一个对象时,只执行一次。
字符串类是一个比较特殊的类,他是Java中唯一重载运算符的类。String的拼接有可能会被编译器优化为StringBuilder来减少对象创建。StringBuilder也是一个类,但是它能够存储可变长度的字符串!。
包其实就是用来区分类位置的东西,也可以用来将我们的类进行分类。(package xxx);
package com.test; public class Test{ }
调用其它包里的类:import
import com.test.*;
.*表示调用包里的全部类。
Java支持对类属性访问的保护,也就是说,不希望外部类访问类中的属性或是方法,只允许内部调用,这种情况下我们就需要用到权限控制符。(private)
权限控制符可以声明在方法、成员变量、类前面,一旦声明private,只能类内部访问!
public class Student { private int a = 10; //具有私有访问权限,只能类内部访问 } public static void main(String[] args) { Student s = new Student(); System.out.println(s.a); //还可以访问吗? }
有些时候我们需要运用到多个数据,一个一个定义很麻烦。这时候我们就要用到数组。数组可以代表任何相同类型的一组内容,其中存放的每一个数据称为数组的一个元素,数组的下标是从0开始,也就是第一个元素的索引是0。
一维数组中,元素是依次排列的(线性)。
类型[] 变量名称 = new 类型[数组大小]; 类型 变量名称n = new 类型[数组大小]; //支持C语言样式,但不推荐! 类型[] 变量名称 = new 类型[]{...}; //静态初始化(直接指定值和大小) 类型[] 变量名称 = {...}; //同上,但是只能在定义时赋值
创建出来的数组每个元素都有默认值,我们可以通过下标去访问:
int[] arr = new int[10]; arr[0] = 626; System.out.println(arr[0]); System.out.println(arr[1]);
获取数组长度:
int[] arr = new int[]{1, 2, 3}; System.out.println(arr.length); //打印length成员变量的值
int[] arr = new int[]{1, 2, 3}; for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); }
int[] arr = new int[]{1, 2, 3}; for (int i : arr) { System.out.println(i); }
foreach属于增强型的for循环,它使得代码更简洁,同时我们能直接拿到数组中的每一个数字。
二维数组其实就是存放数组的数组,每一个元素都存放一个数组的引用。
//三行两列 int[][] arr = { {1, 2}, {3, 4}, {5, 6}}; System.out.println(arr[2][1]);
二维数组的遍历同一维数组一样,只不过需要嵌套循环。
int[][] arr = new int[][]{ {1, 2}, {3, 4}, {5, 6}}; for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { System.out.println(arr[i][j]); } }
不止二维数组,还存在三维数组,也就是存放数组的数组的数组,原理同二维数组一样,逐级访问即可。
可变长参数其实就是数组的一种应用,我们可以指定方法的形参为一个可变长参数,要求实参可以根据情况动态填入0个或多个,而不是固定的数量。
public static void main(String[] args) { test("AAA", "BBB", "CCC"); //可变长,最后都会被自动封装成一个数组 } private static void test(String... test){ System.out.println(test[0]); //其实参数就是一个数组 }
由于是数组,所以说只能使用一种类型的可变长参数,并且可变长参数只能放在最后一位。