有时候真不知道该不该问这样的问题, 只是探讨,没有别的任何意思啊:
new 操作符 已经出现在很多的计算机语言中了, 但是我看到的解释都是通俗的解释: 就是生成了一个对象;产生那样的一块内存地址!问题是这样产生的:原因一: 我看到了一个帖子是探讨main()方法可不可以被继承的问题! 中间呢有人说可以继承,有人说不可以继承,请看下面代码:
Java code
//第一个类
public class Test
{
public static void main(String args[])
{
System.out.println("a main method is running now");
}
}
//第二个类
public class Test2 extends Test
{
}
/*
编译并运行第二个类,打印出
a main method is running now
我看到了这样的一段有趣的代码,当我们在运行 java Test2 的时候, 其实命令是这样的: Test2.main(); 自己没有,从父类里找到了main()方法运行; (个人理解,正确与否还请大家探讨!) 感觉上就象继承了静态方法一样, 或许有人会拿main为一个特殊的方法来做文章,它不过为一个线程而已, 再看下面这个代码:public class Test1 {
public static void main(String args) {
System.out.println("111111111111111");
}
}public class Test2 { public static void main(String [] args) {
Test1.main(new String [] {""}); //能不能执行,还希望亲自实验下比较好哦!
}
}
上面这段代码没有涉及到继承的概念, 主要是说明下main方法也不过是一个普通方法而已!, 前一段时间看的一本书上写了这么一句话, 觉得很在理, 也希望大家能通过这句话能将心中那种迷惑解开:封装的单位是对象; 继承的单位是类;或许有些人对这句话不太理解,没有关系,刚开始看到的时候,我也不理解, 再看看下面这段代码,或许能帮你参悟:public class Test1 {
public static void main(String args) {
Test1 t = new Test2();
t.s(); //最好自己实践看下结果!
}
public static void s() {
System.out.println("test1");
}
}public class Test2 extends Test1{
public static void s() {
System.out.println("test2");
}
}
回过头, 再去看那句话, 为何对象不能?。 new!~构造器!~~ 先想想这些问题!!!!题外话: 为何我要写这么多, 因为我在那个帖子里没有看到一个满意的解释!紧接着他们又探讨到了构造函数, 说构造函数是静态方法, 否则就没有办法调用(说是从Think in java 上看到的,我没看过,无从考证!) 因为没有对象产生, 你怎样去调用方法的?》。其实看过java类装载机制和反射原理的人,在这里会明白其中的原因,我也在此就不多阐述了, 别人说的比我好啊!呵呵!至于构造器究竟是不是个静态方法, 我真的不太清楚,就等有缘人来解答这样的一个问题了!(毕竟我还是个菜鸟吗!)原因二: 与new 能打到交道的有静态初始化块, 初始化块, 父子构造器,他们的初始化顺序, 我就不在此多说了,它代表着new操作符的执行过程, 我们看到的是 当我们new一个子类的时候!发现它会同时的去调用父类的构造器, 感觉就象是产生了无数多的对象嵌套一样! 这就要涉及到多态了,别着急!~ 我们先来看看代码:public class Test1 {
public static void main(String args) {
Test2 t = new Test2(); //看看多态和不多态的时候有什么样区别?
Test1 t = new Test2();
}
public Test1() {
System.out.println("test1");
}
}public class Test2 extends Test1{ public Test2() {
System.out.println("test2");
}
}
感受到那种对象嵌套对象再嵌套那种了吗?。 让我们感觉特想java的类装载机制啊!(这样的知识还是请高人来回答,菜鸟不行)~~, 多态让我们看到,(间接地)引用指向了对象里嵌套的那个父类对象, 但为何重写的方法回执行子类的呢?》 这个对象本身还是子类,它不是父类,那个引用指向的还是子类对象,那为什么父类引用指向子类对象,却无法执行子类中的那些方法(父类中没有的那些方法)呢? 这个吗!!! 高人接班!~~ 我可是真接不上了!! 期待ing ...原因三: 前两天看到了一篇javascript中new 一个对象的帖子, 是这样说的!~ javascript 产生一个对象的过程是这样的: 先产生了一个全新的oject(来自于Object,并非来自其他类,javascript中没有类), 然后通过一个构造函数初始化(请与java中的构造器进行比较) 将所有的参数值赋给这个object! (我们暂且抛开javascript中的原型不谈)
java中产生的对象过程是不是也是如此呢?。 没有考察过!原因四: 对象与对象实例的区别:我们所接触的new操作符, 总是在跟构造器打交道,基本不和别的打交道, 我在java中没有看到说明对象与对象实例的区别, 这是在javascript中提到的!~ 都是面向对象思维,当然也不会有太大的冲突,
在javascript中是这样描述一个对象: 将他的一个function 看成一个对象(也可以简单的看作我们的构造器),当然它和我们java中的构造器是有区别的, 因为在javascript中,这个构造器本身还是一个对象, 来自于prototype,(原型的概念,我们暂且不涉及那么多,感觉跟我们的反射有点象啊! 其实还是有区别!这是基于对象的一个特征!).将new关键字产生出来的称之为对象实例!
或许有人听到这里,觉得感觉就是又将对象剖开了两个层面来思考一样, 其实我也觉得确实有这么一种思考的意思,毕竟它是一门基于对象的语言, 主要在对象上面做思考(这也可能是与java之间的区别吧!~, ), 我们平常面对的就是一个class, 构造器无非就是为我们初始化的, 其他的并没有进行太多的思考!
真是 下笔千言,离题万里啊!~ 真是不好意思!~~ ~~~~
new 操作符 已经出现在很多的计算机语言中了, 但是我看到的解释都是通俗的解释: 就是生成了一个对象;产生那样的一块内存地址!问题是这样产生的:原因一: 我看到了一个帖子是探讨main()方法可不可以被继承的问题! 中间呢有人说可以继承,有人说不可以继承,请看下面代码:
Java code
//第一个类
public class Test
{
public static void main(String args[])
{
System.out.println("a main method is running now");
}
}
//第二个类
public class Test2 extends Test
{
}
/*
编译并运行第二个类,打印出
a main method is running now
我看到了这样的一段有趣的代码,当我们在运行 java Test2 的时候, 其实命令是这样的: Test2.main(); 自己没有,从父类里找到了main()方法运行; (个人理解,正确与否还请大家探讨!) 感觉上就象继承了静态方法一样, 或许有人会拿main为一个特殊的方法来做文章,它不过为一个线程而已, 再看下面这个代码:public class Test1 {
public static void main(String args) {
System.out.println("111111111111111");
}
}public class Test2 { public static void main(String [] args) {
Test1.main(new String [] {""}); //能不能执行,还希望亲自实验下比较好哦!
}
}
上面这段代码没有涉及到继承的概念, 主要是说明下main方法也不过是一个普通方法而已!, 前一段时间看的一本书上写了这么一句话, 觉得很在理, 也希望大家能通过这句话能将心中那种迷惑解开:封装的单位是对象; 继承的单位是类;或许有些人对这句话不太理解,没有关系,刚开始看到的时候,我也不理解, 再看看下面这段代码,或许能帮你参悟:public class Test1 {
public static void main(String args) {
Test1 t = new Test2();
t.s(); //最好自己实践看下结果!
}
public static void s() {
System.out.println("test1");
}
}public class Test2 extends Test1{
public static void s() {
System.out.println("test2");
}
}
回过头, 再去看那句话, 为何对象不能?。 new!~构造器!~~ 先想想这些问题!!!!题外话: 为何我要写这么多, 因为我在那个帖子里没有看到一个满意的解释!紧接着他们又探讨到了构造函数, 说构造函数是静态方法, 否则就没有办法调用(说是从Think in java 上看到的,我没看过,无从考证!) 因为没有对象产生, 你怎样去调用方法的?》。其实看过java类装载机制和反射原理的人,在这里会明白其中的原因,我也在此就不多阐述了, 别人说的比我好啊!呵呵!至于构造器究竟是不是个静态方法, 我真的不太清楚,就等有缘人来解答这样的一个问题了!(毕竟我还是个菜鸟吗!)原因二: 与new 能打到交道的有静态初始化块, 初始化块, 父子构造器,他们的初始化顺序, 我就不在此多说了,它代表着new操作符的执行过程, 我们看到的是 当我们new一个子类的时候!发现它会同时的去调用父类的构造器, 感觉就象是产生了无数多的对象嵌套一样! 这就要涉及到多态了,别着急!~ 我们先来看看代码:public class Test1 {
public static void main(String args) {
Test2 t = new Test2(); //看看多态和不多态的时候有什么样区别?
Test1 t = new Test2();
}
public Test1() {
System.out.println("test1");
}
}public class Test2 extends Test1{ public Test2() {
System.out.println("test2");
}
}
感受到那种对象嵌套对象再嵌套那种了吗?。 让我们感觉特想java的类装载机制啊!(这样的知识还是请高人来回答,菜鸟不行)~~, 多态让我们看到,(间接地)引用指向了对象里嵌套的那个父类对象, 但为何重写的方法回执行子类的呢?》 这个对象本身还是子类,它不是父类,那个引用指向的还是子类对象,那为什么父类引用指向子类对象,却无法执行子类中的那些方法(父类中没有的那些方法)呢? 这个吗!!! 高人接班!~~ 我可是真接不上了!! 期待ing ...原因三: 前两天看到了一篇javascript中new 一个对象的帖子, 是这样说的!~ javascript 产生一个对象的过程是这样的: 先产生了一个全新的oject(来自于Object,并非来自其他类,javascript中没有类), 然后通过一个构造函数初始化(请与java中的构造器进行比较) 将所有的参数值赋给这个object! (我们暂且抛开javascript中的原型不谈)
java中产生的对象过程是不是也是如此呢?。 没有考察过!原因四: 对象与对象实例的区别:我们所接触的new操作符, 总是在跟构造器打交道,基本不和别的打交道, 我在java中没有看到说明对象与对象实例的区别, 这是在javascript中提到的!~ 都是面向对象思维,当然也不会有太大的冲突,
在javascript中是这样描述一个对象: 将他的一个function 看成一个对象(也可以简单的看作我们的构造器),当然它和我们java中的构造器是有区别的, 因为在javascript中,这个构造器本身还是一个对象, 来自于prototype,(原型的概念,我们暂且不涉及那么多,感觉跟我们的反射有点象啊! 其实还是有区别!这是基于对象的一个特征!).将new关键字产生出来的称之为对象实例!
或许有人听到这里,觉得感觉就是又将对象剖开了两个层面来思考一样, 其实我也觉得确实有这么一种思考的意思,毕竟它是一门基于对象的语言, 主要在对象上面做思考(这也可能是与java之间的区别吧!~, ), 我们平常面对的就是一个class, 构造器无非就是为我们初始化的, 其他的并没有进行太多的思考!
真是 下笔千言,离题万里啊!~ 真是不好意思!~~ ~~~~
因为我们都是一样的------奋斗!
public static void main(String[] args) {
当子类没有默认构造器时,系统会给这个子类一个默认构造器,是一个只有super();这句话的空构造器。你其他的说法,关于main方法的,关于继承的,关于多态的,关于new的,都有错误,建议你好好再看看书。
to 5楼 : 静态方法,只根据引用/变量的类型,比如你是 Test1 虽然你用了一个子类,但你调用静态方法,依然是 Test1的。
我想你光是看了下例子程序,便很快的下结论了, 因为你觉得不会有错, 你有没有想过没有引用类型呢?> 有没有想过换的别的地方的情况呢?.
to 6楼同志:
说的很对的,main既然是静态的,它属于该类,不属于对象
可不能盲目的跟风啊!~ 要在实践中去论证它,我们要将书读活, 而不是读死它!!!!
to 8楼 :
(太长了, 没复制,还请见谅啊!)
谢谢啊! 可能是这个脑瓜比较笨, 接触了这么长的时间了, 都无法参透JVM, 虽然提供的信息多数对我这个帖子来说没有什么作用, 但也可以简单的这样去看, 事情本来就没有对错, 看你层次而已了!
to 9 楼:
楼主,我就看你的前面的代码了,后面的没有看。上面的代码连编译都过不去,还怎么能运行出结果呢?
你基础太不好了,闭门修炼去吧!相信你会成功的!
真是太对不起您了!~ 住要是怪我写的仓促,当时在网吧里, 环境恶略, 就连JDK 基本环境都没, 还只能拿Windws自带的记事本敲代码, 所有可能有点小错误了!我在这个回帖的刚开始就澄清了一下, 不过你说代码编译都不过, 就有点....您在好好试试, 您说, 不可行的代码我就不发上来了!
听你的话,... 再去补上个2年基础!!!!!
Jcreator里是这样报错的。
String args [] 不是写反了
你是写成 String args
在Java 语言中,定义数组:String args [] 或 String[] args 都行
二维数组:String [][] str 或 String [] str[] 或 String str[][]
在一个.java源文件中公共类必须是唯一的
象类似说 把两个public 类放到一个文件里运行有错误的问题, 难道这也要说吗?.你既然知道类是public 的 那就是要写成两个java文件了!~ 基本不能运行?> 我不知道你们怎么看待的呢?. 我测试的全都能通过?.为何你们不能通过呢?> 我又不能手把手的教!~
你们看看是不是哪里有遗漏, 或者自己编写或复制有错误的!~~ 我郑重声明.. 上面的程序是有些错误的, 但是我还是希望看的懂的人看, 看不懂的可以看看热闹, 不要去深究, 这个东西涉及到底层JVM的实现, 如果说运行有错误,(我是指大家可以能将那些修改的错误修改过来!), 那是不会出现的!
另外构造器应该是非静态的吧. 因为静态方法是不能访问非静态成员的.
而我们常用的构造器,常常用来访问非静态成员 this.age = age;这样的代码.
this关键字, 所引用的就是由new分配的内存首地址,所以是一种动态的概念. 一个类继承另一个类, 是类概念上的继承, 即类的所有东西都会继承的. 静态方法由于是属于类的,所以肯定也是自动继承过来的,如果在新类中rewrite静
态方法,则会产生一个新方法,而和父类的同名静态方法无关可以理解的是父类的所有东西都会被子类继承, 子类和父类的同名的静态方法是隶属于不同类的方法.它们之间不存在继承关系,是相互独立的.
而动态方法则不然. Test t1 = new Test(23,"abc");这样一条语句的执行顺序如下.
Test:
JVM 加载Test.class文件, 先初始化Test类中的静态成员, 然后执行static{}语句块.
然后再加载相应的动态代码(注意,不是动态数据). 以上所有的都是存在栈中的. 就是我们在代码中所谓的Class对象.Test t1:
申请一块栈内存,一个引用本身的大小(一般为4个字节).命名为t1.它具有了引用Test对象的能力,注意,它同时也能引用Test.class类信息的能力.
(请注意,它只是具有这个能力,但是还不能做到.因为它这时还不确定里面所引用的到底是什么, 有可能是一个Test对象,也可能是Test的子类对象)Test t1 = new Test(23,"abc"):
根据刚才在栈中加载的Test的类信息,执行以下步骤.
1 先malloc一段内存 赋值给this关键字
2 把Test类中的动态成员初始化,数值数据归0,引用类型归null,布尔型归false.
3 然后调用相应的构造器(int age,String name)型的构造器. 然后把传入的参数赋值给相应的动态成员.其实我们会发现,类的基本信息都是存在栈中的. 而堆中所存的一般都是动态数据.
public class Parent
{ public static void main(String[] args)
{
System.out.println("i'm parent");
}}public class Child extends Parent
{
public static void main(String[] args)
{
new Child().output(args);
}
void output(String args[])
{
super.main(args);
}
}
输出结果:
i'm parent
分析得有一定得道理, 不过我觉得还是有些问题, 从你那3个步骤说吧:
1.说先产生一个this, 我非常赞同, 因为在方法里我们发现这个this总是可是使用, 那说明肯定是先产生的,所以这点我同意你!
2. 这点可就说的有错误了, 我们都知道构造器是用来做什么的?。 是用来进行初始化的, 毫无疑问, 既然它有this说明了它不是静态方法, JVM会去找类里的构造函数, 如果有就执行类中的, 如果没有就执行一个默认的,一旦有重栽的构造函数,JVM就只会在类里找, 而不会去调用它自己默认的那个了! 即便是构造函数里有函数也是如此(继承);
3. 所以第3点也是不对了, 初始化的过程是一个传递值的过程, 但不是初始化两次, 那就不叫初始化了!
{
String name;
int age;
private Test() {} //我们可以将它私有,可是一旦私有了它,将无法被继承! public Test(String name, int age) { //我们竟然还可以使用它! 不冲突!
this.name = name;
this.age = age;
} } class Test2
{
public static void main(String [] args) {
Test t = new Test("ttt",12);
System.out.println(t.name);
}
}多有趣的代码!~ 构造方法也是简单的方法而已!~ 没有什么特别之处!! 它的特别之处还是在于JVM的实现原理上啊!
public static void main(String args) {
System.out.println("111111111111111");
}
}public class Test2 { public static void main(String [] args) {
Test1.main(new String [] {""}); //能不能执行,还希望亲自实验下比较好哦!
}
}肯定是两个.java 文件,生成了两个class文件,.class文件是能直接运行在java虚拟机上的,可以理解是两个程序,就像windows里的.exe文件,两个独立的程序,就不用考虑它内部的方法冲突的合理性,可以认为系统就是用这种方法调用每个java程序的,不存在main方法的特殊性,要是特殊也只是怪语言设计者,为何偏偏指名为main,它完全可以叫mian mnia,其它的看迷糊了,还是底子薄啊,学习了
new操作表示建立一个新的对象,肯定会分配新的对象内存(java不允许直接访问内存),创建的时候在构造方法中初始化完成,同时在内部构造一个父类型的对象,可以用super访问,父类型构造时会构造父父类,相关于使用一个new关键字构造父对象,同时会把和这个对象相关的继承树上所有父类型都构造一个。
static 修饰符修饰的方法,表示此方法属于class 类型的方法,此方法被类的所有实例共享,不属于任何实例,当然也不属于子类型的任何实例。
至于继续嘛,描述的子类型是父类型的一种具体类型,