原创为什么java中一切都是对象还要有static
1. static的“由来”
咱们先来分析一下以下代码:public class Demo { public static void m
目录1、static的“由来”2、static的使用场景3、关于static的常见问题4、总结
Java是一种面向对象编程的语言,而对象是客观存在的事物,对同类对象抽象出其共性,便是Java中的类,类是对象的模子,具有相同属性和方法的一组对象的集合。有了类的定义,我们就可以用类来描述世上任何东西。然而,有一个特殊的东西不属于对象,它就是static。
1. static的“由来”
咱们先来分析一下以下代码:
public class Demo { public static void main(String[] args) { //实例化一个p1Person p1=new Person(); p1.name="xiaoming"; p1.speak(); //实例化一个p2 Person p2=new Person(); p2.name="xiaohong"; p2.speak(); }}class Person{String name;//CN是显示初始化值 String country="China"; void speak(){ System.out.println("My name is " name ",my country is " country); }}通过分析上面的代码,不难发现p1和p2两个对象中,存在一个相同的属性值country="China"。接下来我们通过内存示意图来观察下:
从上图中我们可以注意到红色框中的内容是重复存在于堆中的。倘若对象越建越多,那么堆中的重复数据也会越来越多,这样就会导致内存造成不必要的消耗。既然各个对象中都存在同样的数据,那么何不将这些相同的数据单独拿出来并且单独存放呢?现在将Person类中的country字段加上static,其他不做改动:
class Person{ String name; //将数据值相同且共用的用static修饰,成为类变量 static String country="CN"; void speak(){ System.out.println("My name is " name ",my country is " country); }}于是,我们将相同的数据放到静态存储区内,并让静态存储区中的数据共享给所有对象,这样就可以大大减少了不必要的内存损耗,可见static关键字的作用。
2.static的使用场景
在《Java编程思想》有这样一段话:
“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”
这段话虽然只是说明了static方法的特殊之处,但是可以看出static关键字的基本作用,简而言之,一句话来描述就是:方便在没有创建对象的情况下来进行调用(方法/变量)。下面我们就来探讨一下static的几个使用场景。
1)修饰成员变量和成员方法
用static修饰成员变量可以说是该关键字最常用的一个功能,通常将用static修饰的成员变量称为类成员或者静态成员。本文就是通过该使用场景抛砖引玉,描述了static关键字的“由来”。在jvm的内存构造中,会在堆中开辟一块内存空间,专门用来存储用static修饰的成员变量,称为静态存储区,无论我们创建多少个对象,用 static 修饰的成员变量有且只有一份存储在静态存储区中,所以该静态变量的值是以最后创建对象时设置该静态变量的值为准。并且任何对象都可以对静态存储区中的成员变量做出修改,静态存储区中的成员变量的值以最后一次修改为准。值得一提的是,在JDK1.8以前,静态存储区是存放在方法区的,而方法区不属于堆,在JDK1.8之后,方法区中的静态存储区改为到堆中存储。
用static修饰方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this指针的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。
2)静态代码块
静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行,执行顺序为静态代码块—>非静态代码块—>构造方法—>静态方法。我们来运行以下程序:
Public class Main {Static {System.out.println(“静态代码块”);}{System.out.println(“非静态代码块”);}public Main(){System.out.println(“构造方法”);}public static void eat(){System.out.println(“静态方法”);}public static void main(String[] args) {Main main = new Main();Main.eat();}}运行结果:静态代码块非静态代码块构造方法静态方法而在java继承关系中静态代码块、代码块、构造方法的执行顺序为父类静态代码块—>子类静态代码块—>父类代码块—>父类构造—>子类代码块—>子类构造,可以通过下列代码来判断:
public class Demo { public static void main(String[] args) { new H2(); }}//父类H1class H1{ { System.out.println("父类代码块"); } public H1(){ System.out.println("父类构造"); } static{ System.out.println("父类静态代码块"); }}//H2继承H1class H2 extends H1{ static{ System.out.println("子类静态代码块"); } { System.out.println("子类代码块"); } public H2(){ System.out.println("子类构造"); }}运行结果:父类静态代码块子类静态代码块父类代码块父类构造子类代码块子类构造static关键字可以利用这些特性,通过形成静态代码块来优化程序性能。静态代码块可以存在于类的任何一个地方,并且一个类可以有多个静态代码块,在类初次被加载的时候,会按照静态代码块声明的顺序来依此执行,并且只会执行一次。那么,我们就可以利用静态代码块只加载一次的特性,将不需要重复加载的数据放入静态代码块中来优化程序。
3)静态内部类
内部类指的是定义在一个类的内部的类,包含内部类的类成为外部类,而静态内部类指的是用 static 修饰的内部类。定义内部类的好处是外部类可以访问内部类的所有方法和属性,包括私有方法和私有属性。下面通过代码来理解静态内部类的使用:
//定义一个普通外部类public class OutClass {//定义一个普通内部类public class InnerClass{ }}这里我们要想访问普通内部类,就必须先创建外部类的对象,然后通过外部类名.new 创建内部类的实例,例如第一步:OuterClass oc = new OuterClass();第二步:OuterClass.InnerClass in = oc.new InnerClass();。显然,这样的做法不是很友好。
//定义一个普通外部类public class OutClass {//定义一个静态内部类 public static class InnerClass{ }}如果将普通内部类改为静态内部类,添加static关键字,我们就不需要创建外部类的对象,而是可以直接通过外部类名.内部类名来创建实例,例如OuterClass.InnerClass sic = new OuterClass.InnerClass();。这样就会显得简单很多。
3.关于static的常见问题
1)static关键字会改变类中成员的访问权限吗?
不会。Java中的static关键字不会影响到变量或者方法的作用域。在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字。
2)静态变量可以存在于普通方法中吗?
可以。普通方法必须通过对象来调用,静态变量可以直接通过类名来调用,也可以通过对象来调用,所以是可以存在于普通方法中的。
3)静态方法能存在普通变量吗?
不能。因为静态方法可以直接通过类名来直接调用,不用创建对象,而普通变量是必须通过对象来调用的。
4)static 可以用来修饰局部变量吗?
不能。在C/C 中static是可以作用域局部变量的,但是在Java中切记:static是不允许用来修饰局部变量。不要问为什么,这是Java语法的规定。
4.总结
总的来说,static关键字主要作用就是方便在没有创建对象的情况下进行调用方法/变量。当static修饰成员变量和方法时,该变量就成为了所有对象的公共数据,可以直接通过类名来调用而不用创建对象;当static修饰代码块时,该代码块会在类初次被加载的时候被加载,且只会加载一次,这里需要注意加载顺序的问题;当static修饰内部类时,可以使得操作内部类变得想对简单。另外,根据static的特性,产生了一种重要的设计模式——单例设计模式。这里做个简单介绍,程序实例如下:
class Singleton{private static Singleton instance = null;private Singleton(){}public static getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; }}单例设计模式的特点是该类只能有一个实例,为了实现这一功能,必须隐藏类的构造函数,即把构造函数声明为private,并提供一个创建对象的方法,由于构造对象被声明为private,外界无法直接创建这个类型的对象,这里就可以把创建对象的方法声明为static,通过使用类名来调用方法创建对象,从而完成该模式的设计,有兴趣的读者可以深入设计模式来学习。
目前师长号内正在【原创】连载设计模式专题,关于设计模式的文章确实有很多,但师长发现内容雷同比较多,甚至连内容的结构也比较统一单调,连文章的风格也都相去不远。设计模式属于技术体系中比较理论的内容,比较枯燥,要是再套用书本上那种正式严肃的风格去写,会比较痛苦。
而区别于网上复制粘贴,漏洞百出,陈旧不堪的水文,师长号内正在原创设计模式专题,力求浅显易懂,每一篇都是认真雕琢,经过实例验证的。专注原创高质量技术文输出!
设计模式专题:
【原创】让设计模式飞一会儿|①开篇获奖感言【原创】让设计模式飞一会儿|②单例模式【原创】让设计模式飞一会儿|③工厂模式【原创】让设计模式飞一会儿|④原型模式JAVA中什么叫基于对象的设计程序?
这对于你得问题:我给你做以下总结:希望对你有帮助!
变量
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。
方法
方法即对象的行为,为定义在类中的具特定功能的一段独立的小程序,方法也称为函数
方法运行后的返回结果的数据类型,如果没有返回值使用void
声明形式:
(访问权限修饰符)(修饰符)返回值数据类型 方法名(形式参数列表){
执行语句;
return;
}
1
2
3
4
参数类型: 形式参数的数据类型
形式参数:就是一个变量,用于存储调用方法时传递给方法的实际参数
return 用于结束方法
返回值:该方法执行后的结果,该结果会返回给调用者
方法的特点:
定义方法可以将功能代码进行封装。
便于该功能进行复用。 方法只有被调用才会被执行。
方法的出现提高代码的复用性。
方法若没有返回值,则用关键字void表示,那么该方法中的return语句如果在最后一行可以省略不写。
方法中可以调用方法,不可以在方法内部定义方法。
定义方法时,方法的结果应返回给调用者,交由调用者来处理.
方法的重载
方法名相同、参数不同(数量不同、类型不同、顺序不同)、同一作用域。
二、实现关系 实现指的是一个class类实现interface接口(可以是多个)的功能,实现是类与接口之间最常见的关系。在Java中此类关系通过关键字implements明确标识,在设计时一般没有争议性。在UML类图设计中,实现用一条带空心三角箭头的虚线表示,从类指向实现的接口。
四、关联关系 关联体现的是两个类之间语义级别的一种强依赖关系,比如我和我的朋友,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。关联可以是单向、双向的。表现在代码层面,为被关联类B以类的属性形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量。在UML类图设计中,关联关系用由关联类A指向被关联类B的带箭头实线表示,在关联的两端可以标注关联双方的角色和多重性标记。
六、组合关系 组合也是关联关系的一种特例,它体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合。它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束,比如人和人的大脑。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。在UML类图设计中,组合关系以实心菱形加实线箭头表示。
JMS消息结构:消息头、消息属性、消息体。
JAVA中什么叫基于对象的设计程序?
这对于你得问题:我给你做以下总结:希望对你有帮助!
变量
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。
方法
方法即对象的行为,为定义在类中的具特定功能的一段独立的小程序,方法也称为函数
方法运行后的返回结果的数据类型,如果没有返回值使用void
声明形式:
(访问权限修饰符)(修饰符)返回值数据类型 方法名(形式参数列表){
执行语句;
return;
}
1
2
3
4
参数类型: 形式参数的数据类型
形式参数:就是一个变量,用于存储调用方法时传递给方法的实际参数
return 用于结束方法
返回值:该方法执行后的结果,该结果会返回给调用者
方法的特点:
定义方法可以将功能代码进行封装。
便于该功能进行复用。 方法只有被调用才会被执行。
方法的出现提高代码的复用性。
方法若没有返回值,则用关键字void表示,那么该方法中的return语句如果在最后一行可以省略不写。
方法中可以调用方法,不可以在方法内部定义方法。
定义方法时,方法的结果应返回给调用者,交由调用者来处理.
方法的重载
方法名相同、参数不同(数量不同、类型不同、顺序不同)、同一作用域。
二、实现关系 实现指的是一个class类实现interface接口(可以是多个)的功能,实现是类与接口之间最常见的关系。在Java中此类关系通过关键字implements明确标识,在设计时一般没有争议性。在UML类图设计中,实现用一条带空心三角箭头的虚线表示,从类指向实现的接口。
四、关联关系 关联体现的是两个类之间语义级别的一种强依赖关系,比如我和我的朋友,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。关联可以是单向、双向的。表现在代码层面,为被关联类B以类的属性形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量。在UML类图设计中,关联关系用由关联类A指向被关联类B的带箭头实线表示,在关联的两端可以标注关联双方的角色和多重性标记。
六、组合关系 组合也是关联关系的一种特例,它体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合。它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束,比如人和人的大脑。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。在UML类图设计中,组合关系以实心菱形加实线箭头表示。
JMS消息结构:消息头、消息属性、消息体。
JAVA中什么叫基于对象的设计程序?
这对于你得问题:我给你做以下总结:希望对你有帮助!
变量
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。
方法
方法即对象的行为,为定义在类中的具特定功能的一段独立的小程序,方法也称为函数
方法运行后的返回结果的数据类型,如果没有返回值使用void
声明形式:
(访问权限修饰符)(修饰符)返回值数据类型 方法名(形式参数列表){
执行语句;
return;
}
1
2
3
4
参数类型: 形式参数的数据类型
形式参数:就是一个变量,用于存储调用方法时传递给方法的实际参数
return 用于结束方法
返回值:该方法执行后的结果,该结果会返回给调用者
方法的特点:
定义方法可以将功能代码进行封装。
便于该功能进行复用。 方法只有被调用才会被执行。
方法的出现提高代码的复用性。
方法若没有返回值,则用关键字void表示,那么该方法中的return语句如果在最后一行可以省略不写。
方法中可以调用方法,不可以在方法内部定义方法。
定义方法时,方法的结果应返回给调用者,交由调用者来处理.
方法的重载
方法名相同、参数不同(数量不同、类型不同、顺序不同)、同一作用域。
二、实现关系 实现指的是一个class类实现interface接口(可以是多个)的功能,实现是类与接口之间最常见的关系。在Java中此类关系通过关键字implements明确标识,在设计时一般没有争议性。在UML类图设计中,实现用一条带空心三角箭头的虚线表示,从类指向实现的接口。
四、关联关系 关联体现的是两个类之间语义级别的一种强依赖关系,比如我和我的朋友,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。关联可以是单向、双向的。表现在代码层面,为被关联类B以类的属性形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量。在UML类图设计中,关联关系用由关联类A指向被关联类B的带箭头实线表示,在关联的两端可以标注关联双方的角色和多重性标记。
六、组合关系 组合也是关联关系的一种特例,它体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合。它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束,比如人和人的大脑。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。在UML类图设计中,组合关系以实心菱形加实线箭头表示。
JMS消息结构:消息头、消息属性、消息体。
JAVA中什么叫基于对象的设计程序?
这对于你得问题:我给你做以下总结:希望对你有帮助!
变量
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。
方法
方法即对象的行为,为定义在类中的具特定功能的一段独立的小程序,方法也称为函数
方法运行后的返回结果的数据类型,如果没有返回值使用void
声明形式:
(访问权限修饰符)(修饰符)返回值数据类型 方法名(形式参数列表){
执行语句;
return;
}
1
2
3
4
参数类型: 形式参数的数据类型
形式参数:就是一个变量,用于存储调用方法时传递给方法的实际参数
return 用于结束方法
返回值:该方法执行后的结果,该结果会返回给调用者
方法的特点:
定义方法可以将功能代码进行封装。
便于该功能进行复用。 方法只有被调用才会被执行。
方法的出现提高代码的复用性。
方法若没有返回值,则用关键字void表示,那么该方法中的return语句如果在最后一行可以省略不写。
方法中可以调用方法,不可以在方法内部定义方法。
定义方法时,方法的结果应返回给调用者,交由调用者来处理.
方法的重载
方法名相同、参数不同(数量不同、类型不同、顺序不同)、同一作用域。
二、实现关系 实现指的是一个class类实现interface接口(可以是多个)的功能,实现是类与接口之间最常见的关系。在Java中此类关系通过关键字implements明确标识,在设计时一般没有争议性。在UML类图设计中,实现用一条带空心三角箭头的虚线表示,从类指向实现的接口。
四、关联关系 关联体现的是两个类之间语义级别的一种强依赖关系,比如我和我的朋友,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。关联可以是单向、双向的。表现在代码层面,为被关联类B以类的属性形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量。在UML类图设计中,关联关系用由关联类A指向被关联类B的带箭头实线表示,在关联的两端可以标注关联双方的角色和多重性标记。
六、组合关系 组合也是关联关系的一种特例,它体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合。它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束,比如人和人的大脑。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。在UML类图设计中,组合关系以实心菱形加实线箭头表示。
JMS消息结构:消息头、消息属性、消息体。
JAVA中什么叫基于对象的设计程序?
这对于你得问题:我给你做以下总结:希望对你有帮助!
变量
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。
方法
方法即对象的行为,为定义在类中的具特定功能的一段独立的小程序,方法也称为函数
方法运行后的返回结果的数据类型,如果没有返回值使用void
声明形式:
(访问权限修饰符)(修饰符)返回值数据类型 方法名(形式参数列表){
执行语句;
return;
}
1
2
3
4
参数类型: 形式参数的数据类型
形式参数:就是一个变量,用于存储调用方法时传递给方法的实际参数
return 用于结束方法
返回值:该方法执行后的结果,该结果会返回给调用者
方法的特点:
定义方法可以将功能代码进行封装。
便于该功能进行复用。 方法只有被调用才会被执行。
方法的出现提高代码的复用性。
方法若没有返回值,则用关键字void表示,那么该方法中的return语句如果在最后一行可以省略不写。
方法中可以调用方法,不可以在方法内部定义方法。
定义方法时,方法的结果应返回给调用者,交由调用者来处理.
方法的重载
方法名相同、参数不同(数量不同、类型不同、顺序不同)、同一作用域。
二、实现关系 实现指的是一个class类实现interface接口(可以是多个)的功能,实现是类与接口之间最常见的关系。在Java中此类关系通过关键字implements明确标识,在设计时一般没有争议性。在UML类图设计中,实现用一条带空心三角箭头的虚线表示,从类指向实现的接口。
四、关联关系 关联体现的是两个类之间语义级别的一种强依赖关系,比如我和我的朋友,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。关联可以是单向、双向的。表现在代码层面,为被关联类B以类的属性形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量。在UML类图设计中,关联关系用由关联类A指向被关联类B的带箭头实线表示,在关联的两端可以标注关联双方的角色和多重性标记。
六、组合关系 组合也是关联关系的一种特例,它体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合。它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束,比如人和人的大脑。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。在UML类图设计中,组合关系以实心菱形加实线箭头表示。
JMS消息结构:消息头、消息属性、消息体。
java新手为什么java类中要有static静态方法?
1。静态方法的特点: 直接调用类名+方法名,不需要实例化类对象。如: Hello.P();
非静态方法则必须实例化一个对象出来,再通过对象调用该方法如: Hello hello=new Hello(参数1~n); hello.P();
2。程序被打包成.jar文件后(相当于.exe文件),给外界唯一的接口就是main方法。使用者双击.jar文件,其实就是让虚拟机执行main方法。
3。main方法不是提供给程序员的,而是提供给虚拟机和使用客户的。 一个软件你没法让客户知道你内部的详情,当然客户也就没办法知道怎么去实例化对象,更不知道实例化对象时需要输入什么参数了。所以只能采用静态方法。
文章评论