为了账号安全,请及时绑定邮箱和手机立即绑定

有没有办法在Java中模拟C ++的“朋友”概念?

有没有办法在Java中模拟C ++的“朋友”概念?

蝴蝶刀刀 2019-07-25 19:30:11
有没有办法在Java中模拟C ++的“朋友”概念?我希望能够在一个包中编写一个Java类,它可以访问另一个包中的类的非公共方法,而不必使它成为另一个类的子类。这可能吗?
查看完整描述

3 回答

?
三国纷争

TA贡献1804条经验 获得超7个赞

Java的设计者明确拒绝了朋友的想法,因为它在C ++中有效。你把你的“朋友”放在同一个包里。私有,受保护和打包的安全性是语言设计的一部分。

James Gosling希望Java能够成为C ++而不会出错。我相信他觉得朋友是个错误,因为它违反了OOP原则。包提供了一种合理的方式来组织组件而不会过于纯粹的OOP。

NR指出你可以使用反射作弊,但即使只有你没有使用SecurityManager才有效。如果打开Java标准安全性,除非您编写安全策略以明确允许,否则您将无法使用反射作弊。


查看完整回答
反对 回复 2019-07-25
?
www说

TA贡献1775条经验 获得超8个赞

“朋友”概念在Java中很有用,例如,将API与其实现分开。实现类通常需要访问API类内部,但这些不应该暴露给API客户端。这可以使用'Friend Accessor'模式实现,详情如下:

通过API公开的类:

package api;public final class Exposed {
    static {
        // Declare classes in the implementation package as 'friends'
        Accessor.setInstance(new AccessorImpl());
    }

    // Only accessible by 'friend' classes.
    Exposed() {

    }

    // Only accessible by 'friend' classes.
    void sayHello() {
        System.out.println("Hello");
    }

    static final class AccessorImpl extends Accessor {
        protected Exposed createExposed() {
            return new Exposed();
        }

        protected void sayHello(Exposed exposed) {
            exposed.sayHello();
        }
    }}

提供“朋友”功能的课程:

package impl;public abstract class Accessor {

    private static Accessor instance;

    static Accessor getInstance() {
        Accessor a = instance;
        if (a != null) {
            return a;
        }

        return createInstance();
    }

    private static Accessor createInstance() {
        try {
            Class.forName(Exposed.class.getName(), true, 
                Exposed.class.getClassLoader());
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException(e);
        }

        return instance;
    }

    public static void setInstance(Accessor accessor) {
        if (instance != null) {
            throw new IllegalStateException(
                "Accessor instance already set");
        }

        instance = accessor;
    }

    protected abstract Exposed createExposed();

    protected abstract void sayHello(Exposed exposed);}

来自'friend'实现包中的类的示例访问:

package impl;public final class FriendlyAccessExample {
    public static void main(String[] args) {
        Accessor accessor = Accessor.getInstance();
        Exposed exposed = accessor.createExposed();
        accessor.sayHello(exposed);
    }}


查看完整回答
反对 回复 2019-07-25
  • 3 回答
  • 0 关注
  • 454 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信