Java:构造函数、static(静态)

构造方法

构造方法:创建对象,给对象中的成员进行初始化
格式:
1.方法名与类名相同
2.没有返回值类型,连void都没有
3.没有具体的返回值

 public Student() {}

构造方法的重载
1.如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
2.如果我们给出了有参数构造方法,系统将不再提供默认的无参构造方法。
注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法

public Student(String name, int age, String number) {
    this.name = name;
    this.age = age;
    this.number = number;
}
/*
因为已经给出了含有三个参数的构造方法
public Student(){}这个默认构造方法就不存在了
Student s=new Student();这句话将无法执行,因为无法创建无参的对象
所以我们要自己给出无参构造方法
*/
public Student() {}
public Student(String name, int age, String number) 
{
    this.name = name;
    this.age = age;
    this.number = number;
}
static(静态)

如果我们有一个共享数据,比如国籍,在一个国家或者地区的服务器中,国籍都是相同的
如果每一个对象中都存一份国籍很占内存,所以我们可以将国籍这个属性提取出来,使其只存一份,并使其共享,这时就要使用static关键字
被static修饰的成员变量或者成员方法存放在方法区的静态区中
static是一个修饰符,用于修饰成员(成员变量、成员函数)。
当成员被静态修饰后,就多了一种调用方式,除了可以被对象调用外,还可直接被类名调用(类名.静态成员)

class Person
{
	static String country="CN";
}
class  PersonDemo
{
	public static void main(String[] args) 
	{
	   Person p=new Person();
	   System.out.println(p.country);          //这两句的输出结果都是"CN"
	   System.out.println(Person.country);
	}

特有内容随着对象存储,而共有的数据可以用static修饰
方法区(共享区、数据区):存储类中的方法和共享数据

static的特点:

1.随着类的加载而加载 当类加载到内存中,静态成员以及值也加载到内存中,也就是说,静态成员会随着类的消失而消失,他的生命周期最长
2.优先于对象存在
3.被所有对象所共享
4.可以被类名所调用
被静态修饰的成员变量被称为静态成员变量或者叫类变量
没有被静态修饰的成员变量被称为成员变量或者叫实例变量

实例变量和类变量的区别

1.存放位置
类变量随着类的加载存在于方法区中
实例变量随着对象的建立存在于堆内存中
2.生命周期
类变量生命周期最长,随着类的消失而消失
实例变量生命周期随着对象的消失而消失

静态使用的注意事项

1.静态方法只能访问静态成员,非静态方法既可以访问静态也可以访非静态
非静态成员随着对象的创建而存在,静态方法优先于非静态存在,所以不可以调用未存在的方法和变量。而当非静态存在时,静态已经存在
2.静态方法中不可以定义this,super关键字
因为静态优先于对象存在,所以静态方法中不可以出现this关键字
优点:
1.对对象的共享数据进行单独空间的存储,节省堆内存空间,没必要每一个对象中都存储一份数据
2.可以直接被类名调用
缺点:
1.生命周期过长,占用内存
2.访问出现局限性,静态只能访问静态

静态代码块
static
{
	要执行的代码;
}
//随着类的加载而执行,只执行一次,且优先于主函数,用于给类进行初始化
class StaticCode
{
	static
	{
    	System.out.println('a')
	}
}
class StaticCodeDemo
{
	public static void main(String[] args) 
	{
		new StaticCode();        //执行该语句打印a
		new StaticCode();        //因为类已经存在所以该语句不执行
	}
}               
class StaticCode
{
    StaticCode()
   {
       System.out.println('b');        //构造函数
   }
   static
   {
       System.out.println('a');          //静态代码块
   }
   {
       System.out.println('c');          //代码块
   }
    StaticCode(int x)
   {
       System.out.println('d');          //构造函数
   }
}
class StaticCodeDemo
{
   public static void main(String[] args) 
   {
		new StaticCode(4);               
   }                                                             
}
/*
打印结果:
a
c
d
*/
/*
初始化时,先加载类,静态代码块随着类的加载而执行,
之后代码块随着对象的建立而被执行,最后执行对应的构造函数
*/
对象的初始化过程
Person p=new Person("小明",31);
步骤:
1.因为new用到了Person类,所以会先找到Person.class文件并加载到内存中
2.执行该类中的静态代码块(如果有的话),给Person类进行初始化
3.在堆内存中开辟空间,分配内存地址
4.在堆内存中建立对象的特有属性,并进行默认初始化
5.对属性进行显示初始化
6.对对象进行构造代码块初始化
7.对对象进行对应构造函数的初始化
8.将内存地址赋值给栈内存中的p变量
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Java中的构造函数,我们不能像普通方法一样直接使用Clone方法进行克隆,因为构造函数是在创建对象时自动调用的。但是,我们可以使用Javassist库来实现静态构造函数的克隆。 Javassist是一个用于在运行时修改字节码的Java库。我们可以使用Javassist创建一个新的类,并将原始类的所有方法和字段复制到新类中。然后,我们可以在新类中修改构造函数的实现,以实现克隆。 以下是一个示例代码,演示如何使用Javassist创建静态构造函数的克隆: ``` import javassist.*; public class ConstructorClone { public static void main(String[] args) throws Exception { ClassPool pool = ClassPool.getDefault(); CtClass origClass = pool.get("com.example.OriginalClass"); CtClass newClass = pool.makeClass("com.example.NewClass"); // Copy all fields and methods from original class to new class newClass.setSuperclass(origClass); CtField[] fields = origClass.getDeclaredFields(); for (CtField field : fields) { newClass.addField(field); } CtMethod[] methods = origClass.getDeclaredMethods(); for (CtMethod method : methods) { newClass.addMethod(method); } // Clone constructor CtConstructor origConstructor = origClass.getDeclaredConstructor(new CtClass[]{}); CtConstructor newConstructor = CtNewConstructor.copy(origConstructor, newClass, null); newClass.addConstructor(newConstructor); // Modify constructor implementation newConstructor.setBody("{ super(); }"); // Create instance of new class Object newObject = newClass.toClass().newInstance(); } } ``` 在上面的代码中,我们首先获取了原始类的CtClass对象,并创建了一个新的CtClass对象。然后,我们将原始类的所有字段和方法复制到新类中。接下来,我们使用CtNewConstructor.copy方法克隆原始类的构造函数,并将其添加到新类中。最后,我们修改新构造函数的实现,以调用原始构造函数并执行其他操作。 请注意,这只是一个示例代码,实际应用中可能需要更复杂的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值