什么是Java相当于Ruby的单例

时间:2014-04-25 13:24:01

标签: java ruby

在Ruby中,我可以创建特定于实例的方法(单例方法)

class C;end

v1,v2 = C.new, C.new #=>two instances of class C

def v1.meth
  puts "I am only available in instance v1"
end

puts v1.meth #=> prints -> I am only available in instance v1
puts v2.meth #=> throws -> undefined method 'meth'

Java中的等价物是什么?

4 个答案:

答案 0 :(得分:4)

你最接近的是拥有匿名课程。

class C {}

C v1 = C() {
    void meth() {
        puts("I am only available in instance v1");
    }
};
C v2 = new C();

// prints -> I am only available in instance v1
v1.getClass().getMethod("meth").invoke(v1); 
// throws NoSuchMethodException
v2.getClass().getMethod("meth").invoke(v2); 

在Java 8中,您可以编写

interface C {
    void meth();
}

C v1 = () -> puts("I am only available in instance v1");
C v2 = () -> { throws new UnsupportedOperationException(); }

v1.meth();
v2.meth();

在自然Java方法中,静态检查调用,并且不能调用编译器无法确定存在的方法。 (你可以用上面的反射来做到这一点)

答案 1 :(得分:1)

您可以尝试使用策略模式之类的东西来实现这一目标。为实现提供一个抛出UnsupportedOperationException的默认策略。当然这意味着您无法动态添加这些"单例方法",您必须提前创建方法。

答案 2 :(得分:0)

据我所知,Java中没有这样的东西!

答案 3 :(得分:0)

您可以向类的匿名子类添加方法,这种方法感觉“方法仅在该实例中可用”。

无法从外部访问该方法,因为在已知的类合同中缺少该方法,但是在同一匿名子类的该实例中,它可以由其他重写方法调用。

这看起来像这样:

    List<String> list = new LinkedList<String>(){
        @Override
        public int size() {
            if (this.contains("fox"))
                return sizeOfFox();

            return super.size();
        }

        private int sizeOfFox() {
            return 4;
        }};

}

您正在创建LinkedList的匿名子类,该子类包含仅在该实例中可用的其他方法:sizeOfFox()。只要列表包含"fox"之类的字符串,此方法就会被size()方法的重写版本调用。

这种实际用途是有限的,它不能真正与红宝石单身方法相比。通常,在实例化抽象侦听器接口等时使用这种实现,并提取代码路径以保持中央方法的清洁。

注意:在Java中,“单身人士”通常被定义为应用Singleton Design Pattern的结果。