⭐⭐⭐Java基础篇目录⭐⭐⭐
🍁 第一章 Java开发环境搭建
🍁 第二章 标识符与关键字
🍁 第三章 变量
🍁 第四章 数据类型
🍁 第五章 运算符
🍁 第六章 控制语句
🍁 第七章 方法
🍁 第八章 认识面向对象
🍁 第九章 对象的创建和使用
🍁 第十章 封装
🍁 第十一章 this和static
🍁 第十二章 继承
🍁 第十三章 方法的覆盖和多态
🍁 第十四章 super
1、static关键字
关于static关键字:
- static 静态的,所有static修饰的,都是类相关的,类级别的
- 所有static修饰的,都采用 类名. 的方式访问
- static修饰的变量为静态变量,存储在方法区
- static修饰的方法是静态方法
2、静态变量
被static修饰的变量即静态变量,存储在方法区,在类加载时完成初始化,不需要new对象,其空间就开辟出来了。
静态变量的使用场景:
- 若某个属性一个对象一份,则用实例变量,存堆区,如姓名、身份证号
- 若某个属性所有对象都相同,则用静态变量,存方法区,如国籍
这样只在方法区保存一份,可避免不必要的内存空间浪费
//正确访问姿势是通过类名.
Chinese c1 = new Chinese();
System.out.println(Chinese.country);
//使用引用.来访问静态变量也不会报错,但不建议这样用
//这里不会出现空指针异常,会转化成类名.xx
c1 = null;
System.out.println(c1.country);
空指针异常只有在“空引用”访问“实例”相关的时候,才会出现。
什么时候定义的是实例方法?什么时候定义的是静态方法?
如果方法体中需要访问实例变量,则这个方法只能定义成实例方法。如果写成静态方法,而此时无对象,无法去访问实例变量—error:无法从静态上下文中引用非静态变量。
3、静态代码块
关于静态代码块:
- 使用static关键字定义静态代码块
static {
java语句1;
java语句2;
}
- 静态代码块在类加载时执行,且执行一次,存方法区(方法区中存.class等代码片段)
- 静态代码块在main方法执行之前就执行,多个静态代码块则从上而下执行
- 静态代码块是SUN公司给的一个特殊实际–类加载时机,如可用于记载类加载的日志信息
public class StaticTest {
static int var = 1;
static{
System.out.println(var);
}
public static void main(String[] args) {
System.out.println("main execute!");
}
}
适当改一下静态变量和静态代码块的定义顺序
public class StaticTest {
static{
System.out.println(var);
}
//后定义静态变量,而先定义的静态代码块中已经访问了它
static int var = 1;
public static void main(String[] args) {
System.out.println("main execute!");
}
}
静态变量和静态代码块都在类加载时执行,谁先谁后,看代码顺序自上而下。
截至目前,有自上而下顺序要求的有:
- 对于一个方法,方法体中的代码自上而下(两个方法的定义是无先后顺序的)
- 静态代码块1和静态代码块2自上而下
- 静态代码块和静态变量自上而下
4、实例代码块
实例代码块的定义:
{
java语句1;
java语句2;
}
构造方法执行之前,实例代码块必然在构造方法之前自动执行一次。
这是SUN公司准备的又一个特殊时机—-对象构建时机
5、this
this的总结:
- this是一个关键字,全部小写。
- 一个对象,一个this,this是一个变量,是一个引用。
- this保存当前对象的内存地址,指向自身,所以严格意义上来说,this代表的就是当前对象。
this存储在堆内存当前对象内部。
- this只能出现在实例方法中,哪个对象(的引用)调用这个实例方法,this就是谁,所以,this代表的是当前对象。(所以static方法中无this一说)
//定义一个顾客类,此处再回味:类=属性+方法
public class Customer {
String name;
public Customer(){
}
public Customer(String name) {
this.name = name;
}
//定义用户购物的方法
public void shopping(){
System.out.println(name+"正在购物");
//实例变量name的访问为何没使用引用.xx
}
}
程序分析:
实际此处省略了this,this用于实例方法中,代表当前对象。
System.out.println(this.name+"正在购物");
当对象(的引用)c1调用实例方法shopping,则this就是c1,当对象c2调用shopping时,this就是c2。不用this,你直接写c1.name+“正在购物”,且不论c1是局部变量,这样写一个本来所有对象都能用的实例方法就被写死了。
到此也就解释了为啥直接的Setter和Getter不能是静态方法,里面要return 属性或者set 属性,即访问实例变量,有对象的概念,this.name=name;
//创建男人类
public class Man {
String idCard;
String name;
static boolean sex = true;
//引用数据类型.未初始化时,值为null.实例变量
Woman woman;
public Man() {
}
public Man(String idCard, String name, Woman woman) {
this.idCard = idCard;
this.name = name;
this.woman = woman;
}
public Man(String idCard, String name) {
this.idCard = idCard;
this.name = name;
}
}
--------------------
//创建女人类
public class Woman {
String idCard;
String name;
static boolean sex = false;
Man man;
public Woman(){
}
public Woman(String idCard, String name) {
this.idCard = idCard;
this.name = name;
}
public Woman(String idCard, String name, Man man){
this.idCard = idCard;
this.name = name;
this.man = man;
}
}
----------------------
//创建测试类
public class ManTest {
public static void main(String[] args) {
Man man = new Man("123","llg");
Woman woman = new Woman("456","wife");
//注意这里引用数据类型的初始化
man.woman = woman;
woman.man = man;
System.out.println(man.name+"的妻子是"+man.woman.name);
}
}
//测试类
public class Practice {
public static void main(String[] args) {
Book book = new Book("Java基础",199);
book.detail();
}
}
//书籍类
class Book {
private String name;
private int page;
public Book() {
}
public Book(String name, int page) {
this.name = name;
if (this.page < 200) {
System.out.println("页数少于200,自动变为200");
this.setPage(200);
//第一次忘记加return了,结果page一直没改好
return;
}
this.page = page;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setPage(int page){
this.page = page;
}
public int getPage(){
return this.page;
}
public void detail(){
System.out.println("书名:"+name+",页数:"+page);
}
}
变量类型 | 存储位置 | 何时初始化 |
---|---|---|
局部变量 | 栈区 | 方法执行过程中开辟空间 |
实例变量(成员变量) | 堆区 | 构造方法执行时,或者说对象创建时开辟空间 |
静态变量(成员变量) | 方法区 | 类加载时初始化并开辟空间 |
在实例方法或构造方法中,为了区分方法中的局部变量和实例变量,this不能省略。this.name = name;
6、this在构造方法中的妙用
构造方法需要初始化一个固定值,可使用this(xx,xx,xx)调用有参构造方法做为这个构造方法的方法体。
//无参构造
public Date(){
this.year = 2022;
this.month = 10;
this.day = 25;
}
等价于
public Date(){
this(2022,10,25);
}
此处this的作用是代码复用,有构造方法调用构造方法的效果。注意,这种this语句必须是构造器中的第一个语句
,这样自然也就只能出现一次(否在总有一个当第二行)。
//这样的写法error
public Date(){
System.out.println("Hello World!");
this(2022,10,25);
}
this的全部总结:
😃
- this是一个关键字,是一个引用,保存了对象的内存地址,指向自身。
- this可以使用在实例方法,也可使用在构造方法中。
- this出现在实例方法中,代表的是当前对象。
- this不能使用在静态方法中。(静态方法用类名.调用,无对象概念,而this与对象挂钩)
- this在大部分情况中可以省略,如实例方法中访问实例变量不用加this。但用于区分实例变量和局部变量时不能省略。
- this(实参列表)的语法,只能出现在构造方法中的第一行,表示当前构造方法调用本类的其他构造方法,目的是代码复用。
public class Practice2 {
public static void main(String[] args) {
Account account = new Account(10001,2000,0.0123);
Customers customer = new Customers("Smith",account);
customer.getAccount().deposit(100);
customer.getAccount().withdraw(960);
customer.getAccount().withdraw(2000);
//这里访问顾客对象的account属性,不能customer.account
//因为出了Customers类了,private属性只能通过Getter
//customer.getAccount()即account,即Account类的对象
//属性是一个引用,这个引用又能指向另外一个对象,从而调用另外一个对象中的方法
//这样,两个对象就可以组合起来去描述模拟现实生活中的场景了
}
}
/**
* 账户类
*/
class Account{
private int id;
private double balance;
private double annualInterestRate;
public Account() {
}
public Account(int id,double balance,double annualInterestRate){
this.id = id;
this.balance = balance;
this.annualInterestRate = annualInterestRate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getAnnualInterestRate() {
return annualInterestRate;
}
public void setAnnualInterestRate(double annualInterestRate) {
this.annualInterestRate = annualInterestRate;
}
/**
* llg
* 取款方法
* @param money
*/
public void withdraw(double money){
System.out.println("您当前账户余额:"+balance);
if(balance-money<0){
System.out.println("余额不足");
return;
}
balance = balance-money;
//setBalance(this.getBalance()-money);也可以
System.out.println("取款"+money+",余额:"+balance);
}
/**
* llg
* 存款方法
* @param money
*/
public void deposit(double money){
balance = balance+money;
System.out.println("存款成功,存款金额:"+money+",当前余额:"+balance);
}
}
/**
* 顾客类
*/
class Customers{
private String name;
private Account account;
public Customers(String name,Account account){
this.name = name;
this.account = account;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
}
注意这里,同一个类里对余额这个private属性进行访问操作,我使用了引用.xx来完成,当然使用getBalance()方法更可以了。出了本类就只能用set和get了。
小结:
静态方法中访问实例变量或者调用实例方法—->new对象,引用.xxx
实例方法中访问静态变量或者调用静态方法—->类名.xxx,同一个类中类名可省略
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/146122.html