一、this关键字
1.修饰属性
当属性名与形参或局部变量发生重名时,会产生就近原则,所以 要使用this.属性来表示。
在Person类中定义了有参构造,且赋值,然后创建Person类的对象,
package com.rzd.no02oop.demo02;
public class Person {
String name;
int age;
double height;
public Person(){
}
public Person(String name,int age,double height){
//this表示当前这个对象,这里这个有参构造被person1接收,那么this就是指person1
this.name= name;
this.age=age;
this.height=height;
}
}
package com.rzd.no02oop.demo02;
public class Application {
public static void main(String[] args) {
Person person = new Person();
Person person1 = new Person("lisi", 20, 170);
//因为this指的就是person1,那么给this.name赋值也就是给person1.name赋值。
System.out.println(person1.name);
}
}
2.修饰方法
同一个类中,方法可以互相调用,this.可以省略
public void eat(){
System.out.println("我在吃饭");
}
public void play(){
//调用了上面的est方法,this可以省略
this.eat();
System.out.println("我在玩");
3.修饰构造器
this调用构造器必须放在第一行
public Person(String name,int age,double height){
//可以看到这两句话与下面两个参数的构造器重复了,所以可以直接调用下面这个构造器
/*this.name= name;
this.age=age;*/
this(name,age);
this.height=height;
}
public Person(String name,int age){
this.name = name;
this.age=age;
}
二、static关键字
意为静态的,可以修饰属性、方法、代码块、内部类
被static修饰,即在类加载的时候会一起加载到堆中的的静态方法区,先于对象存在
static修饰的内容可以使用 类名.变量/方法名的方式调用,且一般都是使用这种方式
1.修饰属性
每个对象有自己的属性,例如id,年龄等不会相同,但是如果有些属性所有对象都有(例如学生类的对象有相同的学校属性),就可以声明为static类型。
static修饰的属性:静态属性(类变量)
没有static修饰的属性:非静态变量(实例变量)
public class Student {
private static String name; //静态的变量,一般用于多线程中
private int age; //非静态的变量
public static void main(String[] args) {
//要使用这个类,先要初始化这个类
Student student = new Student();
//static修饰的对象我们一般都直接用类.变量的方式调用,而非静态变量不可以
System.out.println(name); //在当前类可以直接调用name,但不能直接调用age
System.out.println(Student.name); //在其他类中可以直接调用类名.name
//System.out.println(Student.age); //这句话报错Non-static field 'age' cannot be referenced from a static context
//也可以通过对象调用
System.out.println(student.name);
System.out.println(student.age);
}
}
如图代码,可以看到3个对对象sid输出的值都是30
package com.rzd.no02oop.demo03;
public class Test {
int id;
static int sid;
public static void main(String[] args) {
Test t1 = new Test();
t1.id=10;
t1.sid=10;
Test t2 = new Test();
t2.id=20;
t2.sid=20;
Test t3 = new Test();
t3.id=30;
t3.sid=30;
System.out.println(t1.id+"\t"+t2.id+"\t"+t3.id); //10 20 30
System.out.println(t1.sid+"\t"+t2.sid+"\t"+t3.sid); //30 30 30
}
}
对这段代码进行内存分析:
2.修饰方法
public class Student {
//static修饰方法
//静态方法
public static void run1(){
}
//非静态方法,在非静态方法中可以直接调用静态方法,因为静态方法是和类一起加载的
public void run2(){
run1();
}
public static void main(String[] args) {
//可以直接调动静态方法run1
run1(); //当前类中调用的写法
Student.run1(); //其它类中调用的写法
//run2();在调用时必须先初始化这个类,否则不能调用
new Student().run2();
}
}
package com.rzd.no02oop.demo03;
public class Test {
int id;
static int sid;
public void a(){
//在非静态方法中可以访问静态属性,因为静态属性在类加载的时候就一起加载了
//也就是等号右边new语句运行的时候就存在了,此时等号左边的对象还没有创建。
System.out.println(id);
System.out.println(sid);
}
public static void b(){
//同理,在静态方法中不能访问非静态变量,因为类加载时,类的对象还没有创建,所以非静态变量还不存在。
//System.out.println(id);//报错
//a(); //也不能访问非静态方法
//System.out.println(this.id); //也不能使用this,因为this指代当前对象,但是此时对象还没有创建
System.out.println(sid);
}
public static void main(String[] args) {
Test t1 = new Test();
//非静态方法必须用对象名.方法名调用,静态方法还可以使用类名.方法名调用
t1.a();
Test.b(); //t1.b();
}
}
3.修饰代码块(见下面静态块章节)
4.静态导入(见下面静态导入章节)
三、代码块
类的组成:属性、方法、构造器、代码块、内部类
代码块可以分为:普通块、构造块、静态块、同步块(多线程)
1.普通块
在方法内,作用域为{}内
2.构造块(匿名代码块)(不常用)
在方法外,一般放不能写在方法内的代码,作用域为{}内
3.静态块
static修饰,在类加载的时候加载,只会加载一次,只能访问静态属性和静态方法,一般写全局性的初始化代码。
三个块的执行顺序为:静态块>构造块>构造器>普通块
public class Test {
public Test(){
System.out.println("构造器");
}
public void a(){
{//普通块,作用范围为块之内
int a = 1;
System.out.println("普通块");
}
//System.out.println(a); //报错
}
{ //构造块
System.out.println("构造块");
}
static {
System.out.println("静态块");
}
public static void main(String[] args) {
Test test = new Test();
test.a();
System.out.println("-----------");
Test test2 = new Test();
test2.a();
}
}
//static修饰代码块
public class Person {
//匿名代码块:没有名字定义的代码块,用于赋初始值,和类一起加载
{
System.out.println("匿名代码块");
}
//静态代码块,和类一起加载,且只会加载一次
static {
System.out.println("静态代码块");
}
//构造方法
public Person() {
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person1 = new Person();
/*第一次初始化这个类的时候,执行顺序为
静态代码块
匿名代码块
构造方法
*/
System.out.println("==============");
Person person2 = new Person();
/*第二次初始化这个类的时候,静态代码块不会再执行。执行顺序为
匿名代码块
构造方法
*/
}
}
四、import
1.命名规则
把公司域名倒置为包名:com.baidu.www
IDEA如果只显示一个包的话就点击右上方设置的 Compact Middle Packages
2.包的导入
A类中使用B类:
A和B都在同一个包下,不使用import
A和B不在同一个包下,要使用import
导入包下所有的类:import com.rzd.base.*
IDEA如何导入包:先输入Data,然后按住Alt+回车,选择第一个Import class
在文件最上方就会自动导入包
在java.lang下的包可以直接使用,无需导入
3.导包没有包含与被包含的关系
例如,包的目录结构为
com
------rzd
------demo01
-------A
------B
------A
这里如果在B类中使用import com.rzd.*,是无法new A();的,因为rzd下也有A类,demo01下也有A类,系统无法分辨使用的是哪一个A类,所以这里必须要在B类中import com.rzd.demo01.A才可以。
4.静态导入
import static 包名
//导入Math包下所有的静态的内容,只有这样导入,才可以直接使用方法名调用Math包下的方法
import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
//可以正常输出
//System.out.println(Math.random());
System.out.println(random());
}
}
//静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class Test {
public static void main(String[] args) {
//要想调用random()方法,需要调用Math.random()
System.out.println(Math.random());
/*但是可以通过静态导入Math.random这个包,实现只写random()来调用
先Ctrl点开Math,查看它属于哪个包。查到是java.lang
于是可以导入import java.lang.Math.random;,但是此时会报错,还需要加上static才行。
*/
System.out.println(random());
System.out.println(PI);
}
}