静态 java_Java中的静态

疑问

先来一段代码:

public class GenericFruit {

static class Fruit{

@Override

public String toString() {

return "fruit";

}

}

static class Apple extends Fruit{

@Override

public String toString() {

return "apple";

}

}

static class Person{

@Override

public String toString() {

return "Person";

}

}

static class GenerateTest{

public void show_1(T t){

System.out.println(t.toString());

}

//在泛型类中声明了一个泛型方法,使用泛型E,这种泛型E可以为任意类型。可以类型与T相同,也可以不同。

//由于泛型方法在声明的时候会声明泛型,因此即使在泛型类中并未声明泛型,编译器也能够正确识别泛型方法中识别的泛型。

public void show_3(E t){

System.out.println(t.toString());

}

//在泛型类中声明了一个泛型方法,使用泛型T,注意这个T是一种全新的类型,可以与泛型类中声明的T不是同一种类型。

public void show_2(T t){

System.out.println(t.toString());

}

}

public static void main(String[] args) {

Person person = new Person(); //如果Person不声明为静态类时,会报错

Apple apple = new Apple();

GenerateTest generateTest = new GenerateTest();

//apple是Fruit的子类,所以这里可以

generateTest.show_1(apple);

//编译器会报错,因为泛型类型实参指定的是Fruit,而传入的实参类是Person

//generateTest.show_1(person);

//使用这两个方法都可以成功

generateTest.show_2(apple);

generateTest.show_2(person);

//使用这两个方法也都可以成功

generateTest.show_3(apple);

generateTest.show_3(person);

}

}

疑问:GenerateTest的main方法,在new一个Person对象和new一个Apple对象时,如果其不声明为static会报错,所以

1、这是 静态方法main的原因 吗?

写一个Demo来看一下:

623e9940368d9e41be4d84e718bafdd6.png

那么问题更具体一些了:

为什么静态方法可以实例化其它非静态非内部类,但是却不可以实例化非静态内部类?

报错:

No enclosing instance of type Father is accessible. Must qualify the allocation with an enclosing instance of type Father (e.g. x.new A() where

x is an instance of Father).

答:可以参考:嵌套类

我理解为非静态内部类相当于是外部类Father的一个“成员变量”,实例化的话,需要通过使用 fa.new Father(); 的方式。

2、静态类中可以有非静态方法吗?

答:可以,但是一个在外部定义的类不能声明为static,声明为static的只能是静态内部类。

理论

一、静态类:

如果一个类要被声明为static,只有一种情况,就是静态内部类,如果在外部定义的类被声明为static,程序会编译不通过。

static关键字使得成员的存储位置为静态区;static是修饰类的成员的,而给类定义,即使是内部类,实例化后也是外部类的一个成员。

静态类中可以有 非静态 变量和方法。

静态类中的 非静态变量和方法 在 实例化的 静态类对象 中可以调用,不能直接使用静态类来调用。

二、静态变量

f3e668b1be4292de1f3968ca7c816e6d.png

教室是同一个,可以是多个对象共享同一份数据,每个对象没有必要针对教室有一份自己独立的数据, 所以为了节约内存可以把所在教室声明为static对象:

0220ce480925c2d68115a55d5204d277.png

一旦使用了static关键字,那么这样的内容不再属于对象自己,而是属于类,所以凡是本类的对象,都共享同一份。

static关键字可以用来修饰成员变量、成员方法。对应的变量、方法不属于对象而是属于类。

对于静态方法来说,可以通过对象名进行调用(正确,不推荐,因为容易误以为是一个普通的成员方法;在编译之后也会被javac翻译为“类名称.成员方法名”),也可以直接通过类名称来调用(强烈推荐)。

注意:

静态不能直接访问非静态

因为在内存中先有的静态内容,后有的非静态方法。“ 先人不知道后人,但是后人知道先人”

静态方法当中不能使用this关键字

因为this代表当前对象,通过谁调用的方法,谁就是当前对象。

三、静态变量的内存图:

?i=202101161947390.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FhcWlhbjE=,size_16,color_FFFFFF,t_70

四、静态方法

在类中使用static修饰的静态方法会随着类的定义而被分配和装载入内存中;而非静态方法属于对象的具体实例,只有在类的对象创建时在对象的内存中才有这个方法的代码段。

静态方法只能访问 静态数据成员 和 静态数据方法。

静态方法中可以声明非静态变量。

public static void put(String set){

return new Abc().set(key);

}

静态方法内每次调用都会使用new产生一个新的Abc对象,原来的对象会一直存在,直到被垃圾回收机制收掉。

静态代码块:

典型用途: 用来一次性地对静态成员变量进行赋值

特点: 当第一次用到本类时,静态代码块执行唯一的一次,静态内容总是优先于非静态,所以静态代码块比构造方法先执行。

代码:

/*

* public class 类名称{

* static{

* //静态代码块的内容

* }

* }

*/

public class Father {

public Father() {

System.out.println("构造方法执行");

}

static{

System.out.println("静态代码块执行"); //静态代码块的内容

}

public static void main(String args[]) {

Father fa = new Father();

Father th = new Father();

}

}

执行结果:

静态代码块执行

构造方法执行

构造方法执行

参考视频:

https://www.bilibili.com/video/BV1ob411j7uh?p=5&t=279

标签:Java,静态,static,new,泛型,静态方法,public

来源: https://blog.csdn.net/aaqian1/article/details/112643822

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值