我正在用C#编写一个小型数据结构库,我遇到了一个架构问题.基本上我有一个实现访问者模式的类,并且有许多可能的访问者实现:
public interface ITreeVisitor<T, U>
{
U Visit(Nil<T> s);
U Visit(Node<T> s);
}
public abstract class Tree<T> : IEnumerable<T>
{
public readonly static Tree<T> empty = new Nil<T>();
public abstract U Accept<U>(ITreeVisitor<T, U> visitor);
}
public sealed class Nil<T> : Tree<T>
{
public override U Accept<U>(ITreeVisitor<T, U> visitor) { return visitor.Visit(this); }
}
public sealed class Node<T> : Tree<T>
{
public Tree<T> Left { get; set; }
public T Value { get; set; }
public Tree<T> Right { get; set; …Run Code Online (Sandbox Code Playgroud) 使用字典时,我总是覆盖GetHashCode和Equals(或者为字典提供自定义比较器).
当我创建一个匿名类作为键时,封面后面会发生什么?
示例代码....
var groups=(from item in items
group item by new { item.ClientId, item.CustodianId, item.CurrencyId }
into g
select new {
Key=g.Key,
Sum=g.Sum(x => x.Cash)
}).ToDictionary(item=>item.Key,item=>item.Sum);
Run Code Online (Sandbox Code Playgroud)
这段代码给了我预期的结果,但我没有为匿名类提供GetHashCode和Equals方法.这段代码不应该根据匿名类中的项目对我的项目进行分组吗?
如何userId在我的匿名内部子类中获取传递给此方法的值?
public void doStuff(String userID) {
doOtherStuff(userID, new SuccessDelegate() {
@Override
public void onSuccess() {
Log.e(TAG, "Called delegate!!!! "+ userID);
}
});
}
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
不能在不同方法中定义的内部类中引用非最终变量userID
我很确定我不能将它指定为final,因为它是一个具有未知值的变量.我听说这种语法确实以某种方式保留了范围,所以我认为必须有一个我还不太了解的语法技巧.
"你为什么要这样做呢?" 尽管如此,有没有办法在不更改最终方法参数名称的情况下完成此操作?
private Foo createAnonymousFoo(final Bar bar) {
return new Foo() {
private Bar bar = SomeUnknownScopeQualifier.bar;
public Bar getBar() {
return bar;
}
public void doSomethingThatReassignsBar() {
bar = bar.createSomeDerivedInstanceOfBar();
}
};
}
Run Code Online (Sandbox Code Playgroud)
显然没有doSomethingThatReassignsBar调用,你就不需要成员Bar等等.在这种情况下,简单的修复是改变final Bar bar为类似的东西final Bar startBar然后分配是好的.但出于好奇,是否可以专门提及final Bar(类似于你想说的方式Super.this)?
我已经读过在Java接口中无法实例化(在文档中,接口).根据定义,Runnable是一个应该由某个类实现的接口.但是在我的一个Android应用程序的下面一段代码中,我看到一个空构造函数 - Runnable()...(我不确定它是否是构造函数)已被使用,并且已经创建了一个实例 - getStatus.
final Runnable getStatus = new Runnable()
{
public void run()
{
TextView uat = (TextView) findViewById(R.id.useAndThrow);
uat.setText(MyThread.getStatus());
return;
}
};
Run Code Online (Sandbox Code Playgroud)
我所知道的:
但我无法连接点.假设上面的代码在myActivity类中,实例化了什么,这个匿名类是什么?
一点细节都会很棒.
我在网上进行了一项小型研究并审查了该网站上的相关主题,但答案是矛盾的:有些人说这是不可能的,有些人说这是可能的,但很危险.
目标是将匿名类的对象作为RMI方法的参数传递.由于RMI要求,此类必须是可序列化的.这没问题,很容易使类Serializable.
但我们知道内部类的实例包含对外部类的引用(而匿名类是内部类).因此,当我们序列化内部类的实例时,外部类的实例被序列化以及字段.这里是问题出现的地方:外部类不可序列化,更重要的是 - 我不想序列化它.我想要做的只是发送匿名类的实例.
简单示例 - 这是一个RMI服务,其方法接受Runnable:
public interface RPCService {
Object call(SerializableRunnable runnable);
}
Run Code Online (Sandbox Code Playgroud)
以下是我想要调用该方法的方法
void call() {
myRpcService.call(new SerializableRunnable() {
@Override
public Object run {
System.out.println("It worked!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我想要做的是向另一方发送"动作" - 系统A描述应该在系统B上运行的代码.这就像用Java发送脚本一样.
如果可能的话,我可以很容易地看到一些危险的后果:例如,如果我们从Runnable访问字段或捕获外部类的最终变量 - 我们将遇到麻烦,因为调用者实例不存在.另一方面,如果我在Runnable中使用安全代码(编译器可以检查它),那么我没有看到禁止此操作的原因.
因此,如果有人知道,如何在匿名类中正确覆盖方法writeObject()和readObject()方法,或者如何引用外部类transient或者解释为什么在java中不可能,它将非常有用.
UPD
另一个需要考虑的重要事项:外部类不存在于将执行该方法的环境中(系统B),这就是为什么应该完全排除有关它的信息以避免NoClassDefFoundError.
从当前的JDK 1.8实现开始,它构建一个匿名对象来保存lambda函数并在这样的对象上调用函数.这个匿名对象是在每次调用中重用,还是每次都重新创建一个对象?
我遇到了一些包含匿名类的代码.我之前没有见过匿名课程,所以我对它们进行了一些研究.
我感兴趣的主要领域是java,所以我检查了Oracle的匿名类教程.我理解机制,我看到了示例的重点,但在我看来,使用匿名类会使代码难以阅读,并且会引起很多麻烦.
是否有任何情况下使用匿名类是不可避免的,或者建议使用它们而不是命名类?
我试过这段代码:
$ac1 = new class {};
$ac2 = new class {};
var_dump($ac1); // object(class@anonymous)#1 (0) {}
var_dump($ac2); // object(class@anonymous)#2 (0) {}
var_dump(new class {}); // object(class@anonymous)#3 (0) {}
var_dump($ac1 == $ac2); // bool(false)
var_dump($ac1 == new class {}); // bool(false)
var_dump($ac2 == new class {}); // bool(false)
Run Code Online (Sandbox Code Playgroud)
上述比较的结果都是错误的.
但是,当我声明一个返回匿名类的函数时,结果如下:
function anonymous_class() {
return new class {};
}
$ac1 = anonymous_class();
$ac2 = anonymous_class();
var_dump($ac1); // object(class@anonymous)#1 (0) {}
var_dump($ac2); // object(class@anonymous)#2 (0) {}
var_dump(anonymous_class()); // object(class@anonymous)#3 (0) {} …Run Code Online (Sandbox Code Playgroud)