static是静态的意思,可以用来修饰属性、方法、代码块、内部类
实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改。
静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。
1.静态变量随着类的加载而加载。可以通过"类.静态变量"的方式进行调用
2.静态变量的加载要早于对象的创建
3.由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中
public class StaticTest {
public static void main(String[] args) {
Chinese c1 = new Chinese();
c1.name = "孔子";
c1.age = 100;
c1.location = "ZY";
Chinese c2 = new Chinese();
System.out.println(c2.location);// ZY
//可以通过直接调用类名的方法来
Chinese.location = "zhongyuan";
System.out.println(c1.location);// zhongyuan
}
}
class Chinese{
String name;
int age;
static String location;
}
1.属性是可以被多个对象所共享的,不会随着对象的不同而不同的。
2.类中的常量也常常声明为static
1.随着类的加载而加载,可以通过"类.静态方法"的方式进行调用
2.静态方法中,只能调用静态的方法或属性;非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性
1.在静态的方法内,不能使用this关键字、super关键字
2.关于静态属性和静态方法的使用,大家都从生命周期的角度去理解
public class StaticTest {
public static void main(String[] args) {
Chinese c1 = new Chinese();
c1.name = "孔子";
c1.age = 100;
c1.location = "ZY";
Chinese c2 = new Chinese();
System.out.println(c2.location);// ZY
Chinese.location = "zhongyuan";
System.out.println(c1.location);// zhongyuan
c2.show();
Chinese.show();
}
}
class Chinese{
String name;
int age;
static String location;
public static void show() {
//无法调用非静态方法或属性
//System.out.println(age);
//info1();
//可以调用静态变量和静态方法,因为生命周期相同
info2();
System.out.println(location);
}
public void info1() {
System.out.println("info1");
}
public static void info2() {
System.out.println("info2");
}
}
1.操作静态属性的方法,通常设置为static的
2.工具类中的方法,习惯上声明为static的。 比如:Math、Arrays、Collections
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。 如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象, 静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。
public class SingletonTest1 {
public static void main(String[] args) {
Bank bank1 = Bank.getInstance();
Bank bank2 = Bank.getInstance();
System.out.println(bank1 == bank2); //true
}
}
//饿汉式
class Bank{
//1.私有化构造器
private Bank() {
}
//2.内部创建类的对象
//4.要求此对象的生命也必须是静态的
private static Bank instance = new Bank();
//3.提供公共的静态的方法,返回类的对象
public static Bank getInstance() {
return instance;
}
}
public class SingletonTest2 {
public static void main(String[] args) {
Order o1 = Order.getInstance();
Order o2 = Order.getInstance();
System.out.println(o1 == o2);//true
}
}
class Order{
//1.私有化类的构造器
private Order() {
}
//2.声明当前类的对象,没有初始化
//4.此对象也必须声明为static的
private static Order instance = null;
//3.声明public、static方法返回当前类对象的方法
public static Order getInstance() {
if(instance == null) {
instance = new Order();
}
return instance;
}
}
由于Java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是 public,又因为Java虚拟机在执行main()方法时不必创建对象,所以该方法必须 是static的,该方法接收一个String类型的数组参数,该数组中保存执行Java命令时传递给所运行的类的参数。
又因为main() 方法是静态的,我们不能直接访问该类中的非静态成员,必须创
建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员,这种情况,我们在之前的例子中多次碰到。
总结:
1.main()方法作为程序的入口
2.main()方法也是一个普通的静态方法
3.main()方法可以作为我们与控制台交互的方式
public class MainTest {
public static void main(String[] args) {
for(int i=0; i<args.length; i++) {
System.out.println("*******" + args[i]);
}
}
}
将MainTest.java文件放入D:\code中,将其中的导包代码去掉。
用来初始化类、对象。只能用static关键字来修饰。
public class BlockTest {
public static void main(String[] args) {
String decs = Person.desc;
System.out.println(decs);
Person p1 = new Person();
Person p2 = new Person();
}
}
class Person{
//属性
String name;
int age;
static String desc = "我在学习java";
//构造器
public Person(){
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//非静态代码块
{
System.out.println("hello, block");
}
//静态代码块
static {
System.out.println("hello, static block!");
desc = "学习java的同时学习很多其他语言!!";
}
//方法
public void eat() {
System.out.println("吃饭");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public static void info() {
System.out.println("Perosn类中的info方法!!");
}
}
可进行初始化赋值的位置:
①默认初始化
②显式初始化/⑤在代码块中赋值
③构造器中初始化
④有了对象以后,可以通过"对象.属性"或"对象.方法"的方式,进行赋值
执行的先后顺序:① - ② / ⑤ - ③ - ④
final可以用来修饰的结构:类、方法、变量
1.final标记的类不能被继承,如:String类、System类、StringBuffer类
2.final标记的方法不能被子类重写,如:Object类中的getClass()
3.final标记的变量(成员变量或局部变量)即称为常量,可以考虑赋值的位置:显式初始化、代码块中初始化、构造器中初始化
使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参。一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值。
使用static final修饰的属性即全局常量
例:一个圆类的测试程序,使用静态变量init来生成每个圆的编号,使用静态变量total来生成圆的总个数。使用静态方法getTotal来查看圆的总个数。
public class CircleTest {
public static void main(String[] args) {
Circle c1 = new Circle();
Circle c2 = new Circle();
Circle c3 = new Circle(1.0);
System.out.println("c1的id:" + c1.getId());
System.out.println("c2的id:" + c2.getId());
System.out.println("c3的id:" + c3.getId());
System.out.println("圆的总数为: " + c1.getTotal() );
}
}
class Circle{
private double radius;
private int id;
private static int total;
private static int init = 1001;
public Circle(){
id = init++;
total++;
}
public Circle(double radius){
this();
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public int getId() {
return id;
}
public double findArea() {
return Math.PI * radius * radius;
}
public static int getTotal() {
return total;
}
}
参考资料:
[1]尚硅谷宋康红java基础教程