呦呵呵丶

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

1、 

ClassAndObjectTest.java
package ketangkehsi3;

public class ClassAndObjectTest {

public static void main(String[] args) {
//创建类的实例,定义一个对象变量引用这一实例
MyClass obj = new MyClass();
//通过对象变量调用类的公有方法
obj.myMethod("Hello");
//给属性赋值
obj.setValue(100);
//输出属性的当前值
System.out.println(obj.getValue());
//直接访问对象公有字段
obj.Information = "Information";
//输出对象公有字段的当前值
System.out.println(obj.Information);
}
}

/**
* 自定义Java类的示例
*/
class MyClass {
// 公有字段
public String Information = "";

// 自定义公有Java实例方法
public void myMethod(String argu) {
System.out.println(argu);
}

// 定义属性:私有字段+get方法+set方法
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}

}

  

 

 2、

早期我们经常这样定义变量
		int value=100;
前面的示例中这样定义变量
		MyClass obj = new MyClass();

  两者有什么区别?

不一样。前面只定义一个变量,后者定义的对象变量。

3、请输入并运行以下代码,得到什么结果?

package ketangkehsi3;

public class Test {

	public static void main(String []args)
	
	{
		Foo obj1=new Foo();
		Foo obj2=new Foo();
		System.out.println(obj1==obj2);
	}
}
class Foo
{
	int value=100;
}

  

原因:

当“==”施加于原始数据类型变量时,是比较变量所保存的数据是否相等

当“==”施加于引用类型变量时,是比较这两个变量是否引用同一对象。

引用代表地址,所以“==”实际上相当于比较两个引用类型变量中保存的对象地址是否相同。

4、对象变量也可以使用“==”判断两变量值是否相等吗?

package ketangkehsi3;

public class dsa {
	public static void main(String []args){
		int value1=100;
		int value2=100;
		System.out.println(value1==value2);
	}

}

  不相等

5、运行TestStaticInitializeBlock.java示例,观察输出结果,总结出“静态初始化块的执行顺序”。

package ketangkehsi3;


class Root
{
	static{
		System.out.println("Root的静态初始化块");
	}
	{
		System.out.println("Root的普通初始化块");
	}
	public Root()
	{
		System.out.println("Root的无参数的构造器");
	}
}
class Mid extends Root
{
	static{
		System.out.println("Mid的静态初始化块");
	}
	{
		System.out.println("Mid的普通初始化块");
	}
	public Mid()
	{
		System.out.println("Mid的无参数的构造器");
	}
	public Mid(String msg)
	{
		//通过this调用同一类中重载的构造器
		this();
		System.out.println("Mid的带参数构造器,其参数值:" + msg);
	}
}
class Leaf extends Mid
{
	static{
		System.out.println("Leaf的静态初始化块");
	}
	{
		System.out.println("Leaf的普通初始化块");
	}	
	public Leaf()
	{
		//通过super调用父类中有一个字符串参数的构造器
		super("Java初始化顺序演示");
		System.out.println("执行Leaf的构造器");
	}

}

public class TestStaticInitializeBlock
{
	public static void main(String[] args) 
	{
		new Leaf();
		

	}
}

  

 

静态初始化块的执行顺序:1.静态初始化块只执行一次。 2.创建子类型的对象时,也会导致父类型的静态初始化块的执行。

 6、

如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?

如果父类有静态成员赋值或静态初始化块,执行静态成员赋值和静态初始化块。如果类有静态成员赋值或静态初始化块,执行静态成员赋值和静态初始化块将类的成员赋予初值。如果构造函数中年存在this()调用则执行。

7、使用上页幻灯片中定义的类,以下代码输出结果是什么?

package ketangkehsi3;


public class InitializeBlockDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		InitializeBlockClass obj=new InitializeBlockClass();
		System.out.println(obj.field);
		
		obj=new InitializeBlockClass(300);
		System.out.println(obj.field);
	}

}

class InitializeBlockClass{
	//下面这句在初始化块之前与之后,会影响到field字段的初始值
	//public int field=100;
	
	{
	    field=200;
	}
	public int field=100;
	public InitializeBlockClass(int value){
		this.field=value;
	}
	public InitializeBlockClass(){
		
	}}

  

 

规律:所有类的变量都默认初始化null,数字类的原始数据类型默认初始化为0。

执行类的成员定义的默认值或类的初始化块,到底执行哪个要看哪一个排在前面。类的初始化块不接收任何的参数,而且只要一创建类的对象,它们就会被执行。因此,适合于封装那些“对象创建时必须执行的代码”。

8、有趣的问题

静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?

举例:

package ketangkehsi3;

public class Example
{
 int x = 3;//类的实例变量,初始化值为3
 static int  y = 4;//类的静态变量,初始化值为4
 public static void method()//静态方法
  {   
   System.out.println("实例变量x = " + new Example().x);//在静态方法中访问类的实例变量需首先进行类的实例化
   System.out.println("静态变量y = " + y);//在静态方法中可直接访问类的静态变量
  }

 public static void main(String[] args) 
    {
         Example.method();
         Example ex = new Example();
        System.out.println("x = " + ex.x);
    }
}

  运行截图:

结果分析:

类中静态的方法或者属性,本质上来讲并不是该类的成员,在java虚拟机装在类的时候,这些静态的东西已经有了对象,它只是在这个类中"寄居",不需要通过类的构造器(构造函数)类实现实例化;而非静态的属性或者方法,在类的装载是并没有存在,需在执行了该类的构造函数后才可依赖该类的实例对象存在。

在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。

静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制。

  public static void main(String[] args) 

{

  Example.method();

  Example ex = new Example();

System.out.println("x = " + ex.x);

}

}

9、代码(StrangeIntegerBehavior.java)输出诡异的结果,原因何在?

package ketangkehsi3;

public class StrangeIntegerBehavior 
{

    
	public static void main(String[] args)
	{

        
		Integer i1=100;
       
		Integer j1=100;
        
		System.out.println(i1==j1);

        
		Integer i2=129;
        
		Integer j2=129;
        
		System.out.println(i2==j2);
    
	}


}

  

原因:在通过valueof方法创建Integer类型对象时,取值范围为[-128,127],数值在这个区间里,指针指向IntegerCache.cache中已经存在的对象引用,当数值超出这个范围,就会创建一个新的对象。而对对象使用“==”是判断两个对象是否是同一个,所以i1 == j1,i2 != j2。

10、总结Java字段初始化的规律

(1)执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”。

(2)执行类的构造函数。

11、Integer类的装箱和拆箱是怎么样实现的?

package ketangkehsi3;


public class BoxAndUnbox {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		int value=100;

		Integer obj=value;  //装箱

		int result=obj*2;     //拆箱

	}

}

  

所谓装箱,就是把基本类型用他们相对应的引用类型包装起来,使他们可以具有对象的特质,如我们可以把int型包装成Integer类的对象,或者把double包装成Double等等。

所谓拆箱,就是跟装箱的方向相反,将Integer及Double这样的引用类型的对象重新简化为值类型的数据。

 深入剖析链接:http://www.cnblogs.com/dolphin0520/p/3780005.html

 

posted on 2017-10-20 13:32  呦呵呵丶  阅读(215)  评论(0编辑  收藏  举报