1.this关键字
1) this关键字在内存中的位置
先看一段代码
public class Customer {
private String name;
public Customer(){
}
public Customer(String _name){
name = _name;
}
public void setName(String _name){
name = _name;
}
public String getName(){
return name;
}
}
public class CustomerTest {
public static void main(String[] args) {
Customer jack = new Customer("jack");
}
}
以上代码在内存中的活动图为(16进制以0x开头,2进制以0b开头,8进制以0开头)
在图中可以看出,this是一个引用,它存储在Java虚拟机堆内存的对象内部,this这个引用保存了当前对象的内存地址,指向自身。任何一个堆内存的Java对象都有一个this。即this代表当前对象,this可以使用在实例方法和构造方法中,this不能出现在带有static的方法中。
2) this在实例方法和实例变量中的使用
-
static的方法中不能使用this 被static修饰的方法称为静态方法,静态方法调用时使用-类名.方法名-调用,不需要创建对象,而this关键字代表的是当前对象,此处冲突。 为什么set、get方法设计为实例方法呢?(不被static修饰) 因为set、get方法操作的是实例变量,"不同对象"调用get方法得到的数据是不同的,强调的是对象,显然调用该方法不能用类名.方法名调用,必须先创建对象,再通过引用去访问 -
this可以出现在实例方法中,它指向当前调用这个方法的对象 因为通过对象名.方法名 调用实例方法,此时一定会提前创建对象,用对象去触发实例方法,实例方法一定要对象才可以调用,而恰好this关键字又代表当前对象,存储在Java虚拟机堆内存的对象内部,即对象的内部。 -
在实例方法中可以直接访问当前对象的实例变量,而this是可以省略的,而在set、get方法中的不能省略。 public class Customer{
private String name;
public Customer(String name){
this.name=name;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public voif shopping(){
System.out.println(name);
System.out.println(this.name);
}
}
public class Test{
public static void main(String[] args){
Customer c=new Customer("jack");
c.shopping();
}
}
jack
jack
从以上代码可知,name和this.name输出的结果是想等的。即当实例方法中要访问实例变量时,可直接通过实例变量名来访问,也可以使用"this."来访问,也就是说在实例方法中访问实例变量时"this."可以省略
-
在一个实例方法中可以直接调用其他的实例方法("this."省略),也可以使用this.方法名调用,相当于对象.方法名. public class Customer{
private String name;
public Customer(String name){
this.name=name;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public void shopping(){
System.out.println(name);
System.out.println(this.name);
System.out.println("调用其他的实例方法"+this.pay());
System.out.println("调用其他的实例方法"+pay());
}
public void pay(){
System.out.println("支付方法");
}
}
public class Test{
public static void main(String[] args){
Customer c=new Customer("jack");
c.shopping();
}
}
-
在main方法中无法直接访问实例方法和实例变量 实例方法要通过对象.方法名或变量名调用(通过引用去访问),而main方法为static类型的,属于类,在类加载的时候执行。在执行main方法时,如对象还没有被创建,所以就还没有"this",因为"this"代表当前对象,没有对象所以不能用this,也就不能直接访问实例方法或变量 。 public class Test{
public void M(){
System.out.println("实例方法");
}
public static void main(String[] args){
M();
new Test().M();
}
}
public class Test{
int i=10;
public static void main(String[] args){
System.out.println(i);
System.out.println(new Test().i);
}
}
3) this在构造方法中的使用
-
在构造方法中的第一行,用来调用本类中其他的构造方法 public class Customer{
private String name;
public Customer(){
this("jack");
}
public Customer(String name){
this.name=name;
}
}
2.static关键字
1) static介绍
- static 表示静态的,属于类,随着类的加载而加载,优先于对象存在
- 可以修饰方法、变量、代码块等,修饰的可以在它所在的类创建对象之前被访问。修饰的方法称为静态方法,修饰的变量称为静态变量,修饰的代码块称为静态代码块
2)静态变量
java中的变量分为局部变量、成员变量(实例变量)和类变量(静态变量)。局部变量存在于栈中,成员变量(实例变量)存在于堆中、静态变量存在于方法区中。实例变量在构造方法执行过程中初始化,静态变量在类加载时初始化。被static修饰的成员变量为静态变量,不需要创建对象就可以被调用(调用方式:类名.变量名)。
(1)变量在什么情况下会声明为静态变量
? 当一个类的所有的对象的某个变量(属性)的值不会随着对象的改变而改变时,可将该变量设定为静态变量(静态属性)
例如:有一个类它的出生年份都是2000年,每个对象的姓名和ID号都不同。
修改前:
class Student {
private String name;
private int id;
private String year;
public Student() {
}
public Student(String name, int id, String year) {
this.name = name;
this.id = id;
this.year = year;
}
public Student(String name, int id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id=" + id +'\'' +
", year=" + year+
'}';
}
public static void main(String[] args) {
Student s1=new Student();
s1.setId(1);
s1.setName("张三1");
s1.setYear("2000");
Student s2=new Student();
s2.setId(2);
s2.setName("张三2");
s2.setYear("2000");
Student s3=new Student();
s3.setId(3);
s3.setName("张三3");
s3.setYear("2000");
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}
}
修改后:
class Student {
private String name;
private int id;
private static String year="2000";
public Student() {
}
public Student(String name, int id, String year) {
this.name = name;
this.id = id;
this.year = year;
}
public Student(String name, int id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id=" + id +'\'' +
", year=" + Student.year+
'}';
}
public static void main(String[] args) {
Student s1=new Student();
s1.setId(1);
s1.setName("张三1");
Student s2=new Student();
s2.setId(2);
s2.setName("张三2");
Student s3=new Student();
s3.setId(3);
s3.setName("张三3");
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}
}
输出的结果均为
Student{name='张三1', id=1', year=2000}
Student{name='张三2', id=2', year=2000}
Student{name='张三3', id=3', year=2000}
(2) 可以用引用来访问静态变量吗?可以的话,这个访问和具体的对象有什么关系?
Student s1=new Student();
System.out.println(s1.year);
可得出:可以用引用来访问静态变量。但实际上,引用所指的对象并没有参与,如果是空引用访问实例变量,那么一定会发生空指针异常,但是以上编译通过了说明实际上并不是通过对象去访问的,而是通过类去访问的。静态变量和静态方法使用“引用”也可以访问,并且空引用访问静态变量和静态方法并不会出现空指针异常。空引用访问实例相关的成员,必然会出现空指针异常。
3)静态代码块
静态代码块在类加载的时候执行,且执行一次。当有多个静态代码块(或者静态代码块和静态变量)同时执行时,执行顺序遵循从上到下依次执行的原则。
class Student {
static{
System.out.println(m);
}
static int m=0;
static{
System.out.println("静态代码块1");
}
public static void main(String[] args) {
System.out.println("main方法");
}
static{
System.out.println("静态代码块2");
}
}
class Student {
static int m=0;
static{
System.out.println("静态代码块1");
}
static{
System.out.println(m);
}
public static void main(String[] args) {
System.out.println("main方法");
}
static{
System.out.println("静态代码块2");
}
}
class Student {
static int m=0;
static{
System.out.println("静态代码块1");
}
static{
System.out.println(m++);
}
public static void main(String[] args) {
System.out.println("main方法");
System.out.println(m);
}
static{
System.out.println("静态代码块2");
}
}
4)静态方法
什么情况下要将方法设置为静态方法?方法描述的是行为,当某一行为不需要对象就可以触发时,可以将该方法设置为静态方法。或者在方法中不需要使用"当前对象"这一概念时,可以设置为静态方法。
5)选择方法是静态的还是非静态的
工具类中的方法为静态方法,使用方法不需要考虑对象,只知道类中的方法可以干我需要的事情时,使用静态方法。这样可以避免不必要的对象的创建
3.this与static相关案例题
小编正在补充中……
|