static关键字:
静态。有个static的成员变量话,该属性有两种调用方法,除了常规的建立一个对象调用之外,还可以不建立对象,直接用类名调用。如,Person.country=p.country。(此时,country定义为static类型)类名.静态成员。
static修饰函数时, 同样用类名可以调用函数。
static:静态修饰符,用于修饰类中的成员变量或成员方法。被修饰的成员可以除了被对象调用外,还可以被类名调用。
静态的属性和方法的所有者是类而不是对象(以前学的都属于对象)。就像以前学的属性,叫实例化变量,就是说,只有建实例了才能出现。
哪些是被对象共享的,哪些是对象特有的,一定要分出来。要是把姓名变静态,那么出来的所有对象,全叫一个名字。因为是共享的。国际是共享的。被静态修饰的内容被对象共享。
静态函数不能引用非静态变量(实例化变量)。因为先有类后有对象。
静态属性和方法是唯一的,在整个内存条上只有一个。如果你建立了一个对象,调用了该类的一个静态属性,赋值,又建立了一个,调用,赋值,则最后两个对象的这个属性相等,都是第二次赋得值,因为修改的是同一个东西。你new对象后,该对象的该属性存的不是属性值,而是地址,指向原来该类的那个静态属性。
静态随着类的加载而加载,建立类了,他的静态属性就在内存中建立了,而非静态的要与对象一起建立。所以静态时早于非静态建立的。而且静态会随着类的消失而消失。非静态是随着对象消失而消失的。静态的生存周期最长。所以,不建议把属性都定义成静态的,浪费内存。
成员变量,又叫实例变量。另外一种叫静态变量,也叫类变量。不同概念:类类型变量,用类定义的变量。
静态使用的注意事项:
1.静态方法只能访问静态成员。非静态方法可以访问静态方法及非静态方法和属性。因为后出来的可以访问先出来的。
2.静态方法中不可以编写this和super关键字。因为静态中无对象。
3.主函数是静态的。这就是为什么当年写程序其中的函数可以不写public
但必须要写static。但当方法不是static的时候,要想调用,就见对象。在静态函数中,new 类名.方法名。
主函数:public
权限修饰符。现在学过三个权限修饰符,第一个public,第二个,private,第三个,前面什么都不写。这是默认权限。第四个protect。后面会介绍这几种修饰符。
static,静态,随类的加载而加载。
void,返回值为空。主函数中有个return;
main,不是关键字,是函数名。但是也不能乱写。乱写的话,可以,但他不是主函数。
参数:是字符串数组类型的数据。主函数也是函数,调用的时候要往里面传参。虚拟机(jvm)往里面穿了什么参数呢?
打印args,结果是那种中括号那种,所以,args值不是空,而是指向一个数组实体。打印长度,为0,结论是,jvm传的就是
new
String【0】;主函数中,只有一个args,是可以改的。那么穿这个有什么用呢?这样在运行的时候,你可以自己定义传进去的东西,是运行的时候,编译完成之后,运行的时候,在类名后面,空格
再加元素,如下:
class StaticDemo
{
public static void main(String[] arge)
{
System.out.println(args[0]);
}
}
编译后,运行时,输入:java StaticDemo haha hehe xixi
则结果是:haha,如果输入:java
StaticDemo则结果是越界。这就是手动传数值,而且你输入的是一个数组。如果你不输入,就传new String[0];
如不愿意往主函数里传值,则再弄一个类,在这个类中,调用一下:StaticDemo.main(arr);(前文已经定义了一个arr数组)。即可完成主函数传值。
静态代码块:
static
{ };他不需要调用,所以没名字。
它随着类的加载而执行,而且只执行一次。因为类只加载一次,可以对类进行初始化。就是类一加载要做什么事情。
他不需要调用就能执行,优先于主函数(当它和主函数在一个类中时),因为一进类,就先执行所有的静态代码块,不论该代码块是写在main前还是后。还有,当你调用demo类,其中有静态代码块的时候,第一次调用时,运行该代码块,第二次调用时就不运行了,因为该类已经在内存中了,也就是上面说的,只执行一次。
有时候,不需要见对象,这个类也会被加载。当类(如Demo)中有静态的方法(如show),在另外一个函数中,就可以用Demo.show。就可以加载该累了。只有这两种加载类的方法。
通过静态代码块,我们就知道,类什么时候进内存,什么时候执行了。
实例代码块:
{····};这个更猛。连任何前缀都没,放在类中,就当该类被建立对象时,它就执行!这点很像构造函数,而且执行不止一次,就是说你建立几个类,她就执行几次,这点与静态代码块不同。实际编程的时候别写这个,因为阅读性太差。记得静态代码块也只能访问静态成员。
设计模式:
就是解决问题行之有效的方法。(是确定的能解决某种问题的最好方法)。java共有23中设计模式。
没有也可以解决,但是麻烦。当你玩到高端的时候,实际就是在玩设计模式。学设计模式时,先要知道它是用来解决什么问题的。今天将第一种:
单例设计模式:
保证一个类在内存中的对象唯一性。例如,你在调一个软件的皮肤时,当你下次启动的时候,还是你改动后的皮肤,而不是原来默认的,这就要求你每次启动就相当于new对象,需要操作的是同一个对象,如果不是,那么就没办法完成下次启动还是这个皮肤的任务。再如ATM机的bank对象只能有一个。
换句话说,不论谁调用这个类,都只有这一个对象,没有其他的对象。
思路:1.不让其他类建立该类对象,因为其他类建立对象能随意建立,无法控制。2.在该类中建立一个本类对象。3.对外提供方法让其他类可以获取该对象即可。
步骤:1.私有化构造函数,没有写出来时就把默认的私有了。如Demo类中,就写private Demo(){}
即可。因为建立对象一定会有一个动作,就是初始化(调用构造函数),控制其他类不能进行初始化,就能完成不能建立对象的任务。
2.建立一个本类对象,并私有和静态。private Demo d=new Demo();
要加private是因为类中的成员变量都要私有。
3.对外提供静态方法让其他类可以获取该对象, 如
public Demo get()
{
return d;
}
但问题也出现了,下文不可能通过建立对象来调用该方法,只能用类名调用,类名只能调用静态方法,所以,public后面加上
static。但当get方法是私有的时候,她也只能调用私有变量,所以,定义d的那个前面也要加上私有。
4.单例设计模式完成!
你在下面写定义多次时,都是这一个对象。
什么时候使用单例设计模式呢》?在对类进行描述的时候,该怎么写就怎么写,写完之后,当你需要该类在内存中只有一份的话,就加上这三步。
单例设计模式还有第二种写法,第一中被称为饿汉式,这一种叫做懒汉式。不常用,因为在多个人同时使用的时候,会出现点小问题。即多线程时出现问题。但也可以避免,后文再讲,
懒汉式如下:
延迟加载。
第一部一样,private Demo(){}
第二部:private static Demo d=null;
第三部:public static Demo get()
{
if(d==null)
d=new Demo();
return d;
}
这个是被调用时才见对象,而饿汉式直接一斤内存就建对象。
这种方法是考点中最常见的,多线程中再说。
单例设计模式在内存中的体现:
静态,被所有对象所共享,就不存在于堆里面了。在共享区(又叫方法区)中。除了静态,其中还有方法。
局部变量在栈里面。
要明白单例设计模式怎样在这三类区域中变换。
java在启动的时候,分为五片区与,另外两篇,了解。本地方法区。
看个程序:
class NewTest
{
NewTest n=new NewTest();
NewTest(){}
public void show(){}
public static void main(String[] args)
{
NewTest n2=new NewTest();
n2.show();
}
}
溢出错误,为什么?
错就错在第一句的建立本类对象上,因为n是该类中的一个成员变量,所以每个NewTest中都会有一个n。首先从main方法进去,在占内存中建个n2,在堆内存中建一个NewTest();n2指向它。此时的NewTest中有一个n,n需要初始化,所以又建了一个新的NewTest,而这个新的中还有一个n,又建新的,以此类推,无穷尽,所以溢出。
这个例子在于告诉我们,建本类对象前面必须加一个static,
此时,新建的n就在共享区中,不在堆内存中的,不会发生溢出了。
理解一下输出语句:
System.out.println();
首先,System是一个类,而out是System的一个成员(明白什么意思,例如成员变量),而不是一个方法,因为他后面没有(),而且还是一个静态成员,因为类名直接调用了。而println是out的一个方法,而不是System的。
所以,实际上你可以自己写一个输出语句函数;
class NewTest
{
public static void main(String[] args)
{
MySystem.out.print("haha");
}
}
class MySystem
{
static MyPrint out=new MyPrint();
}
class MyPrint
{
static String
print(String a);
{
return a;
}
}
本程序表示一种思想,不能执行。
实际上,java中的,System.out.print可以写成
Printstream ps=System.out;
ps.print("````");
系统中的PrintStream相当于我写的MyPrint。
输出语句的原理:其实是通过System这个类中的静态属性out。所应用的对象PrintStream。并使用了该对象的print方法。