源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Java中一些基础概念的使用详解

  • 时间:2020-03-29 07:50 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Java中一些基础概念的使用详解
  [b]类的初始化顺序 [/b]  在Java中,类里面可能包含:静态变量,静态初始化块,成员变量,初始化块,构造函数。在类之间可能存在着继承关系,那么当我们实例化一个对象时,上述各部分的加载顺序是怎样的?   [b]首先来看代码: [/b]
[url=http://jb51.net/article/36864.htm]深入C#字符串和享元(Flyweight)模式的使用分析 [/url][/b]  字符串的反转输出   这种情况下,一般会将字符串看做是字符数组,然后利用反转数组的方式来反转字符串。   眼花缭乱的方法调用   [b]有继承关系结构中的方法调用 [/b]  继承是面向对象设计中的常见方式,它可以有效的实现”代码复用“,同时子类也有重写父类方法的自由,这就对到底是调用父类方法还是子类方法带来了麻烦。   来看下面的代码:
[u]复制代码[/u] 代码如下:
public class PropertyTest {      public static void main(String[] args)      {          ParentDef v1 = new ParentDef();          ParentDef v2 = new ChildDef();          ChildDef v3 = new ChildDef();          System.out.println("=====v1=====");          System.out.println("staticValue:" + v1.staticValue);          System.out.println("value:" + v1.value);          System.out.println("=====v2=====");          System.out.println("staticValue:" + v2.staticValue);          System.out.println("value:" + v2.value);          System.out.println("=====v3=====");          System.out.println("staticValue:" + v3.staticValue);          System.out.println("value:" + v3.value);      }  }  class ParentDef  {      public static final String staticValue = "父类静态变量";      public String value = "父类实例变量";  }  class ChildDef extends ParentDef  {      public static final String staticValue = "子类静态变量";      public String value = "子类实例变量";  }
  输出结果如下:
[u]复制代码[/u] 代码如下:
=====v1===== staticValue:父类静态变量 value:父类实例变量 =====v2===== staticValue:父类静态变量 value:父类实例变量 =====v3===== staticValue:子类静态变量 value:子类实例变量
  [b]结论 [/b]  对于调用父类方法还是子类方法,只与变量的声明类型有关系,与实例化的类型没有关系。   [b]到底是值传递还是引用传递 [/b]  对于这个话题,我的观点是值传递,因为传递的都是存储在栈中的内容,无论是基本类型的值,还是指向堆中对象的指针,都是值而非引用。并且在值传递的过程中,JVM会将值复制一份,然后将复制后的值传递给调用方法。   [b]按照这种方式,我们来看下面的代码: [/b]
[u]复制代码[/u] 代码如下:
public class ParamTest {      public void change(int value)      {          value = 10;      }      public void change(Value value)      {          Value temp = new Value();          temp.value = 10;          value = temp;      }      public void add(int value)      {          value += 10;      }      public void add(Value value)      {          value.value += 10;      }      public static void main(String[] args)      {          ParamTest test = new ParamTest();          Value value = new Value();          int v = 0;          System.out.println("v:" + v);          System.out.println("value.value:" + value.value);          System.out.println("=====change=====");          test.change(v);          test.change(value);          System.out.println("v:" + v);          System.out.println("value.value:" + value.value);          value = new Value();          v = 0;          System.out.println("=====add=====");          test.add(v);          test.add(value);          System.out.println("v:" + v);          System.out.println("value.value:" + value.value);      }  }  class Value  {      public int value;  }
  它的输出结果:
[u]复制代码[/u] 代码如下:
v:0 value.value:0 =====change===== v:0 value.value:0 =====add===== v:0 value.value:10
  我们看到,在调用change方法时,即使我们传递进去的是指向对象的指针,但最终对象的属性也没有变,这是因为在change方法体内,我们新建了一个对象,然后将”复制过的指向原对象的指针“指向了“新对象”,并且对新对象的属性进行了调整。但是“复制前的指向原对象的指针”依然是指向“原对象”,并且属性没有任何变化。   [b]final/finally/finalize的区别 [/b]  final可以修饰类、成员变量、方法以及方法参数。使用final修饰的类是不可以被继承的,使用final修饰的方法是不可以被重写的,使用final修饰的变量,只能被赋值一次。   [b]使用final声明变量的赋值时机:[/b]   1)定义声明时赋值   2)初始化块或静态初始化块中   3)构造函数   来看下面的代码:
[u]复制代码[/u] 代码如下:
class FinalTest  {      public static final String staticValue1 = "静态变量1";      public static final String staticValue2;      static      {          staticValue2 = "静态变量2";      }      public final String value1 = "实例变量1";      public final String value2;      public final String value3;      {          value2 = "实例变量2";      }      public FinalTest()      {          value3 = "实例变量3";      }  }
  [b]finally一般是和try...catch放在一起使用,主要用来释放一些资源。[/b]   我们来看下面的代码:
[u]复制代码[/u] 代码如下:
public class FinallyTest {      public static void main(String[] args)      {          finallyTest1();          finallyTest2();          finallyTest3();      }      private static String finallyTest1()      {          try          {              throw new RuntimeException();          }          catch(Exception ex)          {              ex.printStackTrace();          }          finally          {              System.out.println("Finally语句被执行");          }          try          {              System.out.println("Hello World");              return "Hello World";          }          catch(Exception ex)          {              ex.printStackTrace();          }          finally          {              System.out.println("Finally语句被执行");          }          return null;      }      private static void finallyTest2()      {          int i = 0;          for (i = 0; i < 3; i++)          {              try              {                  if (i == 2) break;                  System.out.println(i);              }              finally              {                  System.out.println("Finally语句被执行");              }          }      }      private static Test finallyTest3()      {          try          {              return new Test();          }          finally          {              System.out.println("Finally语句被执行");          }      }  }
  执行结果如下:
[u]复制代码[/u] 代码如下:
java.lang.RuntimeException     at sample.interview.FinallyTest.finallyTest1(FinallyTest.java:16)     at sample.interview.FinallyTest.main(FinallyTest.java:7) Finally语句被执行 Hello World Finally语句被执行 Finally语句被执行 Finally语句被执行 Finally语句被执行 Test实例被创建 Finally语句被执行
  注意在循环的过程中,对于某一次循环,即使调用了break或者continue,finally也会执行。   finalize则主要用于释放资源,在调用GC方法时,该方法就会被调用。   [b]来看下面的示例: [/b]
[u]复制代码[/u] 代码如下:
class FinalizeTest  {      protected void finalize()      {          System.out.println("finalize方法被调用");      }      public static void main(String[] args)      {          FinalizeTest test = new FinalizeTest();          test = null;          Runtime.getRuntime().gc();      }  }
  执行结果如下:
[u]复制代码[/u] 代码如下:
[b]finalize方法被调用 [/b]
  [b]关于基本类型的一些事儿 [/b]  基本类型供分为9种,包括byte/short/int/long/float/double/boolean/void,每种基本类型都对应一个“包装类”,其他一些基本信息如下:
[u]复制代码[/u] 代码如下:
. 基本类型:byte 二进制位数:8 . 包装类:java.lang.Byte . 最小值:Byte.MIN_VALUE=-128 . 最大值:Byte.MAX_VALUE=127 . 基本类型:short 二进制位数:16 . 包装类:java.lang.Short . 最小值:Short.MIN_VALUE=-32768 . 最大值:Short.MAX_VALUE=32767 . 基本类型:int 二进制位数:32 . 包装类:java.lang.Integer . 最小值:Integer.MIN_VALUE=-2147483648 . 最大值:Integer.MAX_VALUE=2147483647 . 基本类型:long 二进制位数:64 . 包装类:java.lang.Long . 最小值:Long.MIN_VALUE=-9223372036854775808 . 最大值:Long.MAX_VALUE=9223372036854775807 . 基本类型:float 二进制位数:32 . 包装类:java.lang.Float . 最小值:Float.MIN_VALUE=1.4E-45 . 最大值:Float.MAX_VALUE=3.4028235E38 . 基本类型:double 二进制位数:64 . 包装类:java.lang.Double . 最小值:Double.MIN_VALUE=4.9E-324 . 最大值:Double.MAX_VALUE=1.7976931348623157E308 . 基本类型:char 二进制位数:16 . 包装类:java.lang.Character . 最小值:Character.MIN_VALUE=0 . 最大值:Character.MAX_VALUE=65535
  [b]关于基本类型的一些结论(来自《Java面试解惑》) [/b]•未带有字符后缀标识的整数默认为int类型;未带有字符后缀标识的浮点数默认为double类型。 •如果一个整数的值超出了int类型能够表示的范围,则必须增加后缀“L”(不区分大小写,建议用大写,因为小写的L与阿拉伯数字1很容易混淆),表示为long型。 •带有“F”(不区分大小写)后缀的整数和浮点数都是float类型的;带有“D”(不区分大小写)后缀的整数和浮点数都是double类型的。 •编译器会在编译期对byte、short、int、long、float、double、char型变量的值进行检查,如果超出了它们的取值范围就会报错。 •int型值可以赋给所有数值类型的变量;long型值可以赋给long、float、double类型的变量;float型值可以赋给float、double类型的变量;double型值只能赋给double类型变量。   [b]关于基本类型之间的转换 [/b]  下面的转换是无损精度的转换: •byte->short •short->int •char->int •int->long •float->double   [b]下面的转换是会损失精度的:[/b] •int->float •long->float •long->double   除此之外的转换,是非法的。   [b]和日期相关的一些事儿 [/b]  Java中,有两个类和日期相关,一个是Date,一个是Calendar。我们来看下面的示例:
[u]复制代码[/u] 代码如下:
public class DateTest {      public static void main(String[] args) throws ParseException      {          test1();          test2();          test3();      }      private static void test1() throws ParseException      {          Date date = new Date();          System.out.println(date);          DateFormat sf = new SimpleDateFormat("yyyy-MM-dd");          System.out.println(sf.format(date));          String formatString = "2013-05-12";          System.out.println(sf.parse(formatString));      }      private static void test2()      {          Date date = new Date();          System.out.println("Year:" + date.getYear());          System.out.println("Month:" + date.getMonth());          System.out.println("Day:" + date.getDate());          System.out.println("Hour:" + date.getHours());          System.out.println("Minute:" + date.getMinutes());          System.out.println("Second:" + date.getSeconds());          System.out.println("DayOfWeek:" + date.getDay());      }      private static void test3()      {          Calendar c = Calendar.getInstance();          System.out.println(c.getTime());          System.out.println(c.getTimeZone());          System.out.println("Year:" + c.get(Calendar.YEAR));          System.out.println("Month:" + c.get(Calendar.MONTH));          System.out.println("Day:" + c.get(Calendar.DATE));          System.out.println("Hour:" + c.get(Calendar.HOUR));          System.out.println("HourOfDay:" + c.get(Calendar.HOUR_OF_DAY));          System.out.println("Minute:" + c.get(Calendar.MINUTE));          System.out.println("Second:" + c.get(Calendar.SECOND));          System.out.println("DayOfWeek:" + c.get(Calendar.DAY_OF_WEEK));          System.out.println("DayOfMonth:" + c.get(Calendar.DAY_OF_MONTH));          System.out.println("DayOfYear:" + c.get(Calendar.DAY_OF_YEAR));      }  }
  输出结果如下:
[u]复制代码[/u] 代码如下:
Sat May 11 13:44:34 CST 2013 -05-11 Sun May 12 00:00:00 CST 2013 Year:113 Month:4 Day:11 Hour:13 Minute:44 Second:35 DayOfWeek:6 Sat May 11 13:44:35 CST 2013 sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null] Year:2013 Month:4 Day:11 Hour:1 HourOfDay:13 Minute:44 Second:35 DayOfWeek:7 DayOfMonth:11 DayOfYear:131
  需要注意的是,Date中的getxxx方法已经变成deprecated了,因此我们尽量使用calendar.get方法来获取日期的细节信息。   另外,注意DateFormat,它不仅可以对日期的输出进行格式化,而且可以逆向操作,将符合Format的字符串转换为日期类型。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部