阅读pratical java随笔

阅读pratical java随笔

J2SE经典实例

1.import java.awt.Point;  class PassByValue{

public static void modifyPoint(Point pt, int j){pt.setLocation(5,5); j=15 ;    System.out.println(pt +"传值进来 ;" + j);} //进行别名覆盖

  public static void main(String args[]){Point p = new Point(0,0);                                    

int i = 10;  System.out.println(p +"第一次值 " + i);

  modifyPoint(p, i);      //java值传递方式传递了对象的地址,一个reference      

System.out.println(p +"只传了引用,本身值二进制代码没变" + i); }}//局部变量范围有限

2.class Circle{ private double rad;public Circle(double r){rad = r;}

       public void setRadius(double r){rad = r;}  public double radius(){return rad;}}

public class FinalTest{private static final Circle wheel = new Circle(5.0);

public static void main(String args[]){System.out.println(wheel.radius());

wheel.setRadius(7.4);//final修饰对象,只能改变了值,而不能改变引用(地址),如果:wheel=new Circle(7.4)将错误;没有改变wheel的值,只是改变了wheel所指对象的值。

System.out.println("Radius of wheel is now " +wheel.radius());}}//输出7.4


3.class Base{public final void bar(){}}//应用广泛

class Derived extends Base{

// public void bar(){//Attempting to override Base.bar()}}//修饰类,方法不能重写


4.import java.awt.Button;  class ArrayTest{

public static final int arraySize = 3;public static void main(String args[]){

     int[] ia = new int[arraySize];for (int i=0; i<arraySize; i++)

System.out.println("int array initially " + ia[i]);// 整型初始都是0

     Button[] oa = new Button[arraySize];for (int i=0; i<arraySize; i++)

System.out.println("Button array initially " + oa[i]);  }}//类初始都是null

Array和Vector的区别:a.Array有大小限定,而Vector大小是可变的,Array效率高

                       b.Array更新是静态的,而Vector可以动态移动下标,但只能存对象


5.多态在面向对象纯度和扩展性优于instanceof,除非接口不能修改才用后者,如继承库

interface Employee{public int salary();public int bonus();}

class Manager implements Employee{private static final int mgrSal=40000,mgrBonus = 0;

    public int salary(){return mgrSal;}   public int bonus(){return mgrBonus; }}

class Programmer implements Employee{private static final int prgSal=50000;

    private static final int prgBonus = 10000;  public int salary(){return prgSal;}

    public int bonus(){return prgBonus;}}//每个成员充分继承接口,避免型别辨识判断类

class Payroll{public int calcPayroll(Employee emp){return emp.salary() + emp.bonus();}

public static void main(String args[]){Payroll pr = new Payroll();

Programmer prg = new Programmer();Manager mgr = new Manager();

System.out.println(pr.calcPayroll(prg));System.out.println(pr.calcPayroll(mgr));}}

6.一旦不需要类的引用,就将设为NULL。如果有对象存在于程序运行期间的大部分时间,而它们所引用的内存在这段期间内并不需要,那么大片内存就被浪费掉了,因为JVM垃圾回收程序总是先回收新生的短期对象。但在堆的管理算法中会预先分配一些内存供你的程序使用,这样回收的结果并不会影响其他系统进程,只是提高JAVA程序自身运行效率。

class Foo{public static void main(String args[]){Customers cust=new Customers("Data");

 //使用过程中..//Customers object no longer needed.cust = null;//The rest of the app.}}


7.= =和equals:  class Test{public static void main(String args[]){

                  int a = 10;float b = 10.0f;//外附类和Object中都有equals();

    System.out.println("a==b is " + (a==b));//true,不同基本型别实质的值也是相等的

    Integer ia = new Integer(10);Float fa = new Float(10.0f);

    System.out.println("fa.equals(ia) is " + (fa.equals(ia)));}}//false,实质内容不同

如果所使用的class并未实现equals(),请判断Object的缺省方法是否可胜任都不行就重写


8.equals()最佳实现方式就是搭配getClass(),返回运行时类,确保只有相同的class所产生的对象才有机会被视为相等,具体比较多少属性才算相同可自己根据相关属性确定。

class Golfball{private String brand;private String make;private int compression;

public Golfball (String str, String mk, int comp){brand=str;make=mk;compression=comp;}

      public String brand(){return brand;}       public String make(){return make;}

      public int compression(){return compression;}

public boolean equals(Object obj){ if (this == obj)  return true;

      if ((obj != null) && (getClass() == obj.getClass())) {Golfball gb = (Golfball)obj;

if((brand.equals(gb.brand()))&&(make.equals(gb.make())){

return true;}} return false;  }//...}


9.如果要从class B派生class D,要在class D中调用B的equals(),就一定要调用super.equals(),常常因为父类无法修改

 


10.基类与继承类的equals:
class Base{public boolean equals(Object obj){

      if (obj instanceof Base){}//...return true;}}    class Derived extends Base{}

class test{  public static void main(String args[])  {   

Base b = new Base();    Derived d = new Derived();

      //if (d.equals(b))  //Potentially true if Base attributes are equal

      //if (b.equals(d))  //Potentially true if Base attributes are equal//...}  }

a.base class实现了equals(),而derived class没有:假设base class的equals()使用instanceof, 那么derived 和base class对象进行比较,是对称的。

b.base class和derived class 都实现了equals():如果两个class都在equals()中使用instanceof,当调用derived class equals()返回的是false,因为base对象并非derived实体;当调用base class equals()时返回的是true.

c.base class并未实现equals(),但derived class实现了:因为base对象并非derived实体,调用derived class equals()会返回false;因为base此时调用了Object中equals()进行比较两个类的引用是否相同,所以调用base class equals()返回false;

注:如果只允许同一个class所产生的对象被视为相等,通常用getClass();只有在不得不对derived classes与base class进行比较才用instanceof,如父类是库。


11.在try中慎用返回:

import java.io.*;public class Mine{public static void main(String argv[]){

      Mine m = new Mine();System.out.println(m.amethod());}

      public int amethod(){

      try {FileInputStream dis = new FileInputStream("Hello.txt");}

catch (FileNotFoundException fne) {System.out.println("No such file found");

      return -1; }   //因finally一定要执行,这句话最后被执行!,return语句程序终止

      catch(IOException ioe) {  }

finally{System.out.println("finally");} return 0;} }//0打不出,返回一次终止本方法体


12.异常不容忽视(异常可以覆盖):class Hidden{ public static void main (String args[]){

    Hidden h = new Hidden();try {h.foo(); }    catch (Exception e) {

System.out.println("In main, exception: " +e.getMessage()); }}

  public void foo() throws Exception  {

    try {      throw new Exception("First Exception"); } //最先产生异常

    catch (Exception e){ throw new Exception("Second Exception");} //覆盖第一个异常   

finally { throw new Exception("Third Exception"); }}}//最后打印出的异常


13.将异常用vector全部收集: import java.io.*;import java.util.Vector;

class ReadFileExceptions extends Exception{ private Vector excVector;

  public ReadFileExceptions(Vector v){ excVector = v; }

  public Vector exceptionVector() {return excVector; } //...}

class NotHidden{public static void main(String args[]){ NotHidden nh = new NotHidden();

try {nh.readFile();}catch (ReadFileExceptions rfe) { //...  } }

public void readFile() throws ReadFileExceptions{  BufferedReader br1 = null;

         BufferedReader br2 = null; FileReader fr = null;

         Vector excVec = new Vector(2);  //Vector to store exceptions

  try {fr = new FileReader("data1.fil");br1 = new BufferedReader(fr);int i = br1.read();  fr = new FileReader("data2.fil");br2 = new BufferedReader(fr); i = br2.read();

   //... }//finally通常用于内存回收之外的情况,一定执行,如关闭缓存等

  catch (FileNotFoundException fnfe) {excVec.add(fnfe); } //Add exception to Vector   

  catch (IOException ioe){excVec.add(ioe); }  //Add exception to Vector 

  finally {if (br1!=null){try {br1.close();} catch(IOException e) {excVec.add(e);} }

           if (br2 != null){try {br2.close();}catch (IOException e) { excVec.add(e);}}

           if (excVec.size() != 0)  throw new ReadFileExceptions(excVec);}}}


14.try/catch置于循环之外(将异常用于流程控制如强行跳出性能差)class ExcPerf{

  public void method1(int size){int[] ia = new int[size];

    try {  for (int i=0;i<size;i++)ia[i]=i;  } catch (Exception e){} }

  public void method2(int size){  int[] ia = new int[size];

    for (int i=0; i<size; i++){ try { ia[i] = i;} catch (Exception e){} }}

  public static void main(String args[]) { int size = Integer.parseInt(args[0]);

    ExcPerf ep = new ExcPerf();  long start = System.currentTimeMillis();//豪秒

    ep.method1(size);long end = System.currentTimeMillis();

System.out.println("normal took" +(end-start) + " milliseconds");

start=System.currentTimeMillis();ep.method2(size);end=System.currentTimeMillis();

System.out.println("try/catch took " +(end-start) + " milliseconds"); }}

备注:java Djava.compiler=NONE ExcPerf 777777,原始运行可以看出方法1快于方法2;

      但是开启JIT后的运行时间方法1慢于方法2,优化器耗用内存达到的效果.

对于大型运算数据带上JIT效率会在内存和CPU上胜出,自身占用小于优化所得。


15.不要每逢出错时就使用异常:如果是可预料性的就使用传统错误处理方式

int data;MyInputStream in=new MyInputStream(filename.txt);

Data=in.getData();while(data!=0){//Do something;data=in.getData();}

可预料性错误使用异常参与流程控制降低了性能。异常用于非寻常性情况:如文件存在否

int data;MyInputStream in=new MyInputStream(filename.txt);while(true){

try{data=in.getData();}  catch(Exception e){break;}//参与流程控制


16.避免多接口中方法的冲突:interface Bowler{  public void computeScore();}

interface Golfer{ public void computeScore();}//int出错

class Enthusiast implements Golfer, Bowler{public void computeScore(){//...  }}

a.方法名和返回类型都相同编译才能通过;

b.如果接口无法更改,只有用两个类各自继承以实现期望功能,最好在命名时尽量避免。


17.immutalbe class不可变类:多个线程非同步时数据读取不可能修改,没有必要同步控制。

但是需要付出更多的代价,如额外代码。private,final,只有getter()方法而没有setter.

final class PinNumbers{ private String acctOwner; private int checkingAcctPin;

    private int savingsAcctPin;PinNumbers(String owner, int cPin, int sPin) {

    acctOwner = owner;checkingAcctPin = cPin; savingsAcctPin = sPin; }

public String accountOwner() {return acctOwner;}public int checkingPin(){

    return checkingAcctPin;}public int savingsPin(){return savingsAcctPin; } }


18.实现不可变类时,必须对传入或传出mutable类进行clone.(如上例各成员都不可变除外)

如存在构造方法,不管构造方法是什么访问权限都可传入数据,因为是值传递方式。

final class User1{ private String userName; User1(String name)  {userName = name;}

    public String userName()  {return userName; }

    public void setUserName(String name){userName = name; }   }

final class DiskDriveInfo1{private User1 driveShare;

DiskDriveInfo1(User1 share){driveShare=share;} 

    public User1 share( )  {return driveShare;} }

public class TestClone{ public static void main(String args[])  {

    User1 share1 = new User1("Duke");//输出值为Duke,Fred

    System.out.println("User is " +share1.userName());

    DiskDriveInfo1 dd = new DiskDriveInfo1(share1);User1 share = dd.share();

share1.setUserName("Fred");System.out.println("User is " +share.userName());}}

高效的代码=良好的设计+明智的数据结构+精简的算法,可操作性和可移植更重要


19.如果不变类与mutable类引用交流,clone可变类:shallow clone浅层克隆,如果cloned类包含了一些类引用(已经有new产生),那么新的类将内含与该类的引用完全一致的副本

class User implements Cloneable{  private String userName;

  User(String name){ userName = name; }

  public void setUserName(String name) {userName = name; }

  public String userName() {return userName;}

  public Object clone(){try{return super.clone();} 

                        catch(Exception e){e.getMessage();}return userName; }}

final class DiskDriveInfo{ private User driveShare;

  DiskDriveInfo(User share){driveShare = (User)share.clone(); }

  public User share() {return (User)driveShare.clone();}}//输出值为Duke,Duke

public class Test{ public static void main(String args[])  {

    User share1 = new User("Duke");DiskDriveInfo dd = new DiskDriveInfo(share1);           

  User share = dd.share();System.out.println("User is " +share.userName());

  share1.setUserName("Fred");  System.out.println("User is " +share.userName()); }}


20.Clone()之中首先必须调用super.clone(),可确保java.lang.Object的clone()最终会被调用,因而使得克隆件得以被正确建构出来;任何class如果支持克隆操作,就必须实现cloneable interface,这是一个宣称支持克隆操作的标识接口。

你可能感兴趣的:(阅读pratical java随笔)