如何在Java中找到调用方法的对象 [英] How to find the object that called a method in Java

查看:158
本文介绍了如何在Java中找到调用方法的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以找到在Java中调用方法的对象吗?我有一个团体和人的社交网络。如果一个人想要离开一个团体,只有那个人可以从团体中移除,没有其他人可以移除那个人,不管怎样,调用该方法的人必须证明它的身份。

can I find the object who called a method in Java? I have a social network with groups and persons. If a person wants to leave a group, only that can remove itself from the group, nobody else can remove that person, somehow the person who called the method must prove it's identity.

推荐答案

检查方法的调用者是来自没有经验的程序员的一个非常常见的请求。我很惊讶它在SO上看起来并不常见。但这是一个非常糟糕的想法(只需查看Java 2(可能更糟糕的是更早)安全模型)。

Checking the callers of a method is a quite common request from inexperienced programmers. I'm surprised that it doesn't appear more often on SO. But it's a really incredibly bad idea (just check out the Java 2 (and perhaps worse earlier) Security Model).

在某些情况下,实施此限制很重要。正如Oli Charlesworth所说,只是不要这样做。但是我们假设它很重要,但我们不打算进行堆栈检查。

There are few circumstances where it's important to implement this restriction. As Oli Charlesworth say, just don't do it. But let's assume that it is important, but we're not going to do stack inspection.

让我们首先假设我们信任该组。一种有效但荒谬的方法是向该群体传递一个对象,该对象只代表该人可以创建的人。 (注意Java语言访问限制是基于类的。不同的实例可以创建这样的替代,但代码必须在 Person 类中。)

Let's start by assuming we trust the group. A working but nonsensical approach is to pass to the group an object standing in for the person that only the person can create. (Note Java language access restrictions are class-based. A different instance could create such a stand in, but the code would have to be within the Person class.)

public final class Group { // Can't have a malicious subclass.
    public void deregisterPerson(Person.Standin standin) {
        Person person = standin.person();
        ...
    }
}
public class Person { // May be subclassed.
    public final class Standin { // Could be one per Person.
        private Standin() { // Hide constructor from other outer classes.
        }
        public Person person() {
            return Person.this;
        }
    }
    private void groupDeregister(Group group) {
        group.deregisterPerson(new Standin());
    }
 }

如果我们不信任该群体,那么我们可以扩展替身以引用该组。这可以防止恶意组将某个人从其他组中取消注册。

If we don't trust the group, then we could extend the stand-in to reference the group. This prevents a malicious group deregistering a person from other groups.

public class Group { // Can have malicious subclasses.
    public void deregisterPerson(Person.GroupDeregister deregister) {
        if (deregister.group() != this) { // Not equals...
            throw new IllegalArgumentException();
        }
        Person person = deregister.person();
        ...
    }
}
public class Person { // May be subclassed.
    public final class GroupDeregister {
        private final Group group;
        private GroupDeregister(Group group) { // Hidden.
            this.group = group;
        }
        public Person person() {
            return Person.this;
        }
        public Group group() {
            return group;
        }
    }
    private void groupDeregister(Group group) {
        group.deregisterPerson(new GroupDeregister(group));
    }
 }

另一种方法是制作公开版本的可以接触他人的人。

Another approach is to make a "public" version of Person that can be exposed to others.

public class Person { // "PrivatePerson"
    public PublicPerson publicPerson() {
         return new PublicPerson(this);
    }
    private void groupRegister(Group group) {
        group.registerPerson(this);
    }
    private void groupDeregister(Group group) {
        group.deregisterPerson(this);
    }
    ...
}
public class PublicPerson {
    private final Person person;
    public PublicPerson(Person person) {
        this.person = person;
    }
    @Override public final boolean equals(Object obj) {
        return obj instanceof Person && (Person)obj.person == person;
    }
    @Override public final int hashCode() {
        return person.hashCode();
    }
    ...methods, but no raw registration...
 }
 public class Group {
     private final Set<Person> members = new IdentityHashSet<>(); // No Object.equals.
     public void registerPerson(Person person) {
         members.add(person);
     }
     public void deregisterPerson(Person person) {
         members.remove(person);
     }
     public Set<PublicPerson> members() {
         // This will be more concise in Java SE 8.
         Set<PublicPerson> publics = new HashSet<>();
         for (Member member : members) {
             publics.add(member.publicPerson());
         }
         return unmodifiableSet(publics);
     }
}

Objects.requireNonNull 遗漏了简洁。)

这篇关于如何在Java中找到调用方法的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆