页面

显示标签为“java”的博文。显示所有博文
显示标签为“java”的博文。显示所有博文

2012-02-02

java方法重写

java方法重写(overriding)要点:

  1. 不能重写被标示为final的方法;
  2. 静态方法不能被重写为非静态的方法;
  3. 重写方法的访问修饰符一定要大于被重写方法的访问修饰符(public > protected > default > private); 
  4. 被重写的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行重写(即如果不能继承一个方法,则不能重写这个方法);
  5. 重写方法的参数列表必须完全与被重写的方法的严格相同(不能为子类),否则不能称其为重写,而是重载;
  6. 重写的方法能够抛出更少或更有限的异常(也就是说,被重写的方法声明了异常,但重写的方法可以什么也不声明);
  7. 重写的方法所抛出的异常类型必须和被重写方法的所抛出的异常一致,或者是其子类;
  8. 重写的方法的返回值类型必须和被重写的方法的严格相同(不能为子类)。

2011-09-06

debian中java字体显示为方框

那是因为java字体配置文件中指定的字体不存在了。在debian中,集中修改这个文件(根据实际情况调整路径):
/etc/java-6-sun/fontconfig.properties
找到这一行:
sequence.allfonts=latin-1,chinese-arphic1
后面的值可能会有变化。简单起见,我首选中文:
sequence.allfonts=chinese-arphic1,latin-1
同样地,再根据locale设置调整具体字体(sequence.allfonts.UTF-8.zh.CN,sequence.allfonts.UTF-8.zh.TW,sequence.allfonts.GBK,等等):
sequence.allfonts.UTF-8.zh.CN=chinese-arphic1,latin-1,chinese-arphic2
然后搜索这个chinese-arphic1,应该有这么个东西:
allfonts.chinese-arphic1=-arphic-ar pl shanheisun uni-medium-r-normal--*-*-*-*-p-*-iso10646-1
其值就是jvm字体名,据此再搜‘-arphic-ar pl shanheisun uni-medium-r-normal--*-*-*-*-p-*-iso10646-1’,找其具体字体文件,应该找到这样一行:
filename.-arphic-ar_pl_shanheisun_uni-medium-r-normal--*-*-*-*-p-*-iso10646-1=/usr/share/fonts/truetype/uming.ttc
我早先把uming.ttc给卸载了,所以该字体根本不存在了。把值改为你想要的字体文件:
filename.-arphic-ar_pl_shanheisun_uni-medium-r-normal--*-*-*-*-p-*-iso10646-1=/usr/share/fonts/truetype/wqy/wqy-microhei.ttc
可以顺便把所有引用了不存在的字体‘/usr/share/fonts/truetype/uming.ttc’的项改掉。
搞定。

2011-07-21

java.util.concurrent包中ConcurrentSkipListMap和ConcurrentHashMap释疑

The follows are edited from http://www.java-forums.org/new-java/13840-hashmap-vs-skiplistmap.html:
Constant concurrency vs constant access time (roughly!)

They're essentially horses for courses: they both have different behaviour in terms of (a) time of operations on the map as the size increases, (b) contention and time of operations as concurrent accesses increase, and (c) the overall time of operations if you need to access the data (or a subset) in sorted order.

With a ConcurrentHashMap, time to perform operations (inserts, removes, updates) is essentially constant whatever the size of the map (with very occasional "blips" when the map needs re-hashing). With ConcurrentSkipListMap, as with a plain TreeMap, the time increases by a roughly constant factor every time the number of items in the map doubles. (On my off-the-shelf AMD dual core, that factor is roughly 1.5.) This means that for most practical sizes and small numbers of concurrent threads, ConcurrentHashMap provides faster access in raw terms (with a size of 16 thousand entries and 4 threads, ConcurrentHashMap is about 4 times faster on my test machine).

However, ConcurrentSkipListMap has at least two interesting features in return for poorer access time:
(1) the keys are kept in sorted order, with fast methods to pull out any sorted subset;
(2) it is highly concurrent: with a given size of map, access time is practically constant however many threads are concurrently accessing it; although ConcurrentHashMap provides "good" concurrency, contention and access times do ultimately increase with concurrency. So although with 4 threads, ConcurrentHashMap is faster in raw terms, there'll reach a certain number of threads where ConcurrentSkipListMap overtakes it. (N.B. In practice, I think this will be scores of threads, though.)

So it depends a bit on if you need constant access time or constant concurrency, and/or permanently sorted keys.

For some measurements on ConcurrentHashMap, you may be interested in an article I put up about the performance of ConcurrentHashMap. I'll be adding similar information about ConcurrentSkipListMap fairly soon.

2011-04-03

java泛型参数

泛型参数的擦写采用就近原则:若最近声明为泛型参数,那就是个泛型参数,否则为class或interface。例如:public class A implements B, Comparable { ... A声明T为泛型参数,因此B中的T与A中的T同为一个泛型参数;如果再无其它泛型参数,则K应为class或interface,需明确声明。

java泛型纯粹是垃圾。

2011-03-12

java查看线程信息

可以通过操作系统向JVM发送thread dump信号来查验潜在的线程死锁。这里有篇文章阐述了如何做:
http://www.crazysquirrel.com/computing/java/basics/java-thread-dump.jspx

2011-01-25

关于java函数参数传递的精辟论述

原文在这里:
http://www.yoda.arachsys.com/java/passing.html
下面是节选:
Parameter passing in Java - by reference or by value?

This is another common question on Java newsgroups, made worse by the fact that people who should know better still perpetuate the following myth: Myth: "Objects are passed by reference; primitives are passed by value."

Some proponents of this then say:"Ah, except for immutable objects which are passed by value ..." which introduces loads of rules without really tackling how Java works. Fortunately the truth is much simpler:
Truth #1: Everything in Java is passed by value. Objects, however, are never passed at all.

That needs some explanation - after all, if we can't pass objects, how can we do any work? The answer is that we pass references to objects. That sounds like it's getting dangerously close to the myth, until you look at truth #2:
Truth #2: The values of variables are always primitives or references, never objects.

This is probably the single most important point in learning Java properly. It's amazing how far you can actually get without knowing it, in fact - but vast numbers of things suddenly make sense when you grasp it.

2011-01-18

java中使用enum实现单例

据说是目前比较好的java单例实现方式:

public enum Top {

    INSTANCE;

    public String toString() {
        return "TOP object";
    }

}

2011-01-17

java变量绑定

本来题目想写“java变量赋值与函数参数绑定”,太啰唆,就直接“变量绑定”了。

言简意赅:对基本类型,都是对值进行复制后再绑定;对对象引用变量,则概括为绑定对象地址。

这不同于c/c++(以及go),对基本类型或非基本类型都是(通过拷贝构造函数等)进行复制后再绑定。一句话:java里的变量绑定遵从直觉。

2010-12-12

Java Object Address

`Object.hashCode()' returns the address (maybe, just a relative address) of an object reference. However, if the `hashCode()' method is overridden, it returns something else than a pointer. Actually, there is no safe way to get the reference to an object in Java, but a safe way to check: ==. One always wishes to compare a reference with others when wants it, so why doesn't compare directly.

Java equals, compareTo, and compare

See here:
http://leepoint.net/notes-java/data/expressions/22compareobjects.html

2010-07-28

java构造函数

  1. 每个类都是调用自己的一系列构造函数中的一个。
  2. 被调用的构造函数中没有super调用的话,将先依次调用基类的默认构造函数,且都是在调用完基类构造函数后才执行本身构造函数内的代码。
  3. 任何类,只要定义了一个带参构造函数,同时没有定义默认构造函数,那么java不会为其提供默认构造函数。
下面是从这里整理的:
  1. 子类在初始化的时候,Java将自动调用基类的默认构造器;
  2. 当基类只有带参数的构造器时,子类的构造器必须显式的利用super关键字调用基类的构造器;
  3. 当基类有多个构造器且其中包含默认构造器,而且子类不显式的调用基类的构造器时,Java将自动调用基类的默认构造器;即:父类并不一定要有默认的无参数构造器。分为两种情况:
    1. 有默认构造器,那么子类在不显示调用有参父类构造器的时候,会隐式调用该默认构造器。
    2. 没有默认构造器,那么子类必须显示调用有参父类构造器。
又:隐式调用父类无参数构造器的情况:
  1. 父类仅有无参数构造器,子类肯定会隐式调用;
  2. 父类有多个构造器,且其中包含无参数构造器,且子类没有显式调用父类的有参构造器,那么会隐式调用无参数构造器。

2010-07-24

Java注释

Java Annotation技术旨在提供一个不影响程序语义而可以指导外部工具反射地做出判断的一种技术。这里是个入门的例子:
http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/guide/language/annotations.html

2010-07-17

Java clone方法既深copy

Object类中的clone方法是protected的,要提供给外部使用,必须(直接或间接)实现标志接口java.lang.Cloneable。

容器类(ArrayList等)提供的clone方法只是浅copy(shallow copy),即重新生成并保存了指向目标类的一系列指针。要实现深copy,必须通过新容器对象的添加方法添加目标对象的clone。如:list_x.add(obj.clone())。即目标对象应很好地实现clone方法。但目前,传统的clone方法设计模式在泛型编程时会出现问题:
public class Foo<T extends Cloneable> {
    T obj;
    public Object clone() {
        obj.clone();
    }
}
这段代码无法通过编译:obj继承有Object的clone方法,但不能从外部调用;Cloneable是个空的、标志接口,没有声明clone方法。所以,obj没有公开的clone方法供调用。

一个设计策略是由Cloneable接口派生一个接口,其中声明clone方法,然后泛型约束到该接口。如下列代码所示:
public interface IClone implements Cloneable {
    public Object clone();
}

public class Foo<T extends IClone> {
    T obj;
    public Object clone() {
        obj.clone();
    }
}

一个更加健壮的clone方法实现是通过反射技术,如下列代码:
public MyClass<T> clone( ) throws CloneNotSupportedException { 

    MyClass<T> clon = null; 

    try {  
         clon = (MyClass<T>)super.clone(); 
    } catch (CloneNotSupportedException e) {  
         throw new InternalError();  
    } 

    try { 
       Class<?> clzz = this.field_a.getClass(); 
       Method meth = clzz.getMethod("clone", new Class[0]); 
       Object dupl = meth.invoke(this.field_a, new Object[0]); 
       clon.field_a = (T)dupl;  
    } catch (Exception e) { 
       throw new CloneNotSupportedException (e.toString()); 
    }

}

实际编程中,很难事先设计周全,经常遇到涉及类没有完整实现clone方法的情况,此时,可使用下列通过序列化技术实现的深copy方法(注意:此方法要求被clone的对象实现java.io.Serializable接口):
import java.io.*;
import java.util.*;

/**
   This class is a tool to clone an object deeply.
*/
public class Cloner {

    private Cloner() {
    }

    /**
       This method returns a deep copy of an object.
       @param src the source object to be cloned
       @return a deep copy of src
    */
    public static Object clone(Object src) throws Exception {

 ObjectOutputStream oos = null;
 ObjectInputStream ois = null;

 try {

     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     oos = new ObjectOutputStream(bos);
     // serializing and passing the object
     oos.writeObject(src);
     oos.flush();
     ByteArrayInputStream bin = new ByteArrayInputStream(bos.toByteArray());
     ois = new ObjectInputStream(bin);
     // returning the new object
     return ois.readObject();

 } catch (Exception e) {
     System.out.println("Exception in Cloner: " + e);
     throw(e);
 } finally {
     oos.close();
     ois.close();
 }
    }

}

2009-04-23

实现图数据结构、算法的Java类库

JGraphT开源项目用Java实现了常用的图的数据结构及算法,它的主页在这里:
http://www.jgrapht.org/
关于Java图运算的另一备选方案是NeatGraph,在这里:
http://neatgraph.com/

2009-02-02

JRE Fonts Configuration

Edit file:
$JAVA_HOME$/jre/lib/fontconfig.properties
Actually, one may just replace OpenJDK's fontconfig.properties with Sun JRE provided (search fontconfig.properties in file system and copy).

2008-07-10

Java类初始化过程

  1. 超类静态成员:超类静态变量,超类静态初始化块
  2. 静态成员:静态变量,静态初始化块
  3. 超类非静态成员:超类变量,超类初始化块,超类默认构造器
  4. 非静态成员:变量,初始化块,构造器。
注意:构造器的调用,总是先调用父类;隐式即调用无参构造函数时,默认从根类调用无参构造函数。
这里有个清楚的实例:
http://stanlyy.javaeye.com/blog/452462

2008-05-24

搞懂java中的synchronized关键字[转载]

本文摘自littlebat的BLOG
实际上,我关于Java的基础知识的90%以上都来自Thinking in Java。对于其中的synchronized关键字,当时就是浏览一下,大概知道意思,也没有细看。后来一直没有用过这个关键字。昨天看Thinking in Patterns with Java中的Observer模式,看了其中的Observable类的源码,发现里面几乎所有的方法都用了synchronized关键字(不是全部),其中个别用了synchronized(this){}的区块。于是,我发觉有必要好好理解一下这个关键字了。

我再次看了侯捷译的Thinking in Java第二版中文版,得到有关synchronized的如下信息:
  1. synchronized关键字的作用域有二种:
    • 是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的 synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;
    • 是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。
  2. 除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;
  3. synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;
  4. 疑问:
    我知道了有static区块(其中的加载时机好像也不清楚,需要学习一下,原来看Thinking in Java好像是说: static区块加载的时机是类的一个对象实例创建或类的一个static方法被访问,但是我今天早上看了javaeye.com上面的一个关于 “”的文章后又有点迷糊了:),也许,需要认真学习一下JVM的内在机制才是理解这类问题最根本的途径),也有 synchronized区块,那么,有synchronized static 区块吗?意思是问:有没有一个类作用域内的synchronized区块?

2008-04-23

基于 gcj 的 swing 或 awt 程序依赖包

在 gcj 作为 jdk 的编译环境中,要开发 swing 或 awt 应用,必须安装包 libgcj7-awt:aptitude install libgcj7-awt。目前 debian 版本:etch r2。