先问下,问什么不能new自己。
成都创新互联公司是一家以成都网站建设公司、网页设计、品牌设计、软件运维、成都网站推广、小程序App开发等移动开发为一体互联网公司。已累计为成都玻璃贴膜等众行业中小客户提供优质的互联网建站和软件开发服务。
当然,假如按楼主的写法,当这个A第一次被调用的时候,就出抛异常,超出堆栈、内存溢出之类。
楼主,你需要理解“声明”和“实例化”的概念。
A a;
即是声明,创建了一个A类型的变量a
new A();
即是实例化,实实在在地在内存里为A()划分了一块内存空间
a=new A();即是使a指向new A()。以后只要你不更改a的引用,对a的任何操作都会影响到你分配出来的这块内存空间。
理解了这个再回到问题
public class A{}
这个是对类的一个定义,此时,A只是一个“概念”,在电脑里并没有实体存在,但是java的虚拟机(jvm)已经得知了该类的所有定义,就是说,该类被加载进jvm的类加载器(class loader)了,其他的类有可能访问到该A类。
此时A本身就是jvm中的一个类,它自己当然是和自己同包,对不对?
所以A必然可以访问到A
那么public class A{ A a=new A();}
这句话,编译期是正确的,不存在错误,所以可以声明也(被jvm认为)可以实例化。
但是到了运行期,真正的跑起来的时候,它是错误的
因为这是个迭代的死循环。
在new A()的时候,又会执行一遍A a= new A();
然后该new A()又执行一遍A a= new A();
如此往复,直到堆栈溢出。
当然 以下写法是正确的
public class A{
A a=null;
}
嗯,事实上,有些专门的写法,如单例,工厂类,就是需要在某个类里面实例化它本身。这个,楼主等你基础打好了,再研究吧。
第一对花括号是属于构造方法的,第二对花括号括出了类的动态代码块,每次构造对象时都会执行动态代码块。
另外动态代码块是在构造方法之前执行的。
package demo;
//使用反射
//Class.forName(className)).newInstance()
class Reflect {
static {
System.out.println("动态创建Reflect类,这是静态代码块");
}
public void speak() {
System.out.println("动态创建Reflect类");
}
}
public class ReflectDemo {
public static void main(String[] args) throws Exception {
Class? Demo = Class.forName("demo.Reflect");
Reflect test = (Reflect) Demo.newInstance();
test.speak();
}
}
测试结果:
动态创建Reflect类,这是静态代码块
动态创建Reflect类
静态常量是属于类的属性,只有有了类,就有了这儿常量,不能变动的,所以就不能再动态语句里赋值使用了,只能在初始化赋初值,静态块中执行,而动态语句基本都是方法,是在堆中的,地址、内容属于可变化的,两者属性不一致