我正在尝试创建一个设置,其中一组子类覆盖超类.这个超类包含一个抽象方法 - 理想情况下,它的返回类型是调用此方法的对象的返回类型,因此它的行为如下:
public abstract class SuperClass{
public abstract SuperClass getSelf();
}
public class SubClass extends SuperClass{
@Override
public SubClass getSelf(){
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定这样的事情是否可能,因为我认为返回类型总是必须相同才能使覆盖工作 - 但是我一直在想答案,如果存在的话,就在这条线的某个地方......
public abstract class SuperClass{
public abstract <? extends SuperClass> getSelf();
}
public class SubClass extends SuperClass{
@Override
public SubClass getSelf(){
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助.
编辑:添加扩展SuperClass到SubClass,呃
我有一个while循环,我希望它在经过一段时间后退出.
例如:
while(condition and 10 sec has not passed){
}
Run Code Online (Sandbox Code Playgroud) 这样的事情是我想要实现的:
public Attribute<?> getAttribute(Class<? extends Attribute> attributeClass){
for(Attribute attribute: attributes)
if(attributeClass.isInstance(attribute)) return attributeClass.cast(attribute);
return null;
}
Run Code Online (Sandbox Code Playgroud)
其中Attribute <?>显然是不正确的部分.
我希望这个方法的返回类型是attributeClass,但我似乎无法弄清楚如何得到它.我应该注意到我知道我可以使用Attribute作为返回类型,但是这种方法通常以这种方式调用:
AttributeType1 attributeType1 = getAttribute(AttributeType1.class);
Run Code Online (Sandbox Code Playgroud)
......我试图避免每次都要施展.
帮助赞赏.
对不起,这是一个很长的问题.
我最近在多线程中进行了大量的研究,因为我慢慢将其应用到个人项目中.然而,可能由于存在大量略微不正确的例子,在某些情况下使用同步块和波动对我来说仍然有点不清楚.
我的核心问题是:当一个线程在同步块内时,对引用和原语的更改是自动易失性的(即,在主内存而不是缓存上执行),或者读取是否也必须同步才能使其工作正常吗?
(请注意以下示例,我知道同步方法和synchronized(this)是不赞成的,为什么,但对此的讨论超出了我的问题的范围)
例1:
class Counter{
int count = 0;
public synchronized void increment(){
count++;
}
public int getCount(){
return count;
}
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,increment()需要同步,因为++不是原子操作.因此,两个同时递增的线程可能导致计数总体增加1.count原语需要是原子的(例如,不是long/double/reference),并且它很好.
getCount()需要在这里同步吗?为什么呢?我听到的最多的解释是,我不能保证返回的计数是增量前还是后增量.然而,这似乎是一些略有不同的解释,那就是错误的地方.我的意思是如果我要同步getCount(),那么我仍然看不到保证 - 它现在归结为不知道锁定顺序,不知道实际读取是在实际写入之前/之后.
例2:
以下示例线程是否安全,如果您假设通过此处未显示的技巧,这些方法中的任何一个都不会同时被调用?如果每次都使用随机方法完成,那么计数会以预期的方式递增,然后被正确读取,还是锁定必须是同一个对象?(顺便说一句,我完全意识到这个例子是多么荒谬,但我对理论比对实践更感兴趣)
class Counter{
private final Object lock1 = new Object();
private final Object lock2 = new Object();
private final Object lock3 = new Object();
int count = 0;
public void increment1(){
synchronized(lock1){
count++;
}
}
public void increment2(){ …Run Code Online (Sandbox Code Playgroud) 我正在用Java设计一个游戏引擎.
这个引擎的核心是两个类Asset和Attribute,其中Asset有一个Attributes列表.大多数属性不需要链接回其属性,这意味着属性可以并且经常出现在多个资产的列表中.但是,有一个名为UniqueAttribute的Attribute扩展,它是特定于其Asset的那些实现,并使用链接返回.
理想情况下,如果我删除其他代码,我的Asset的addAttribute方法看起来像这样:
public void addAttribute(Attribute attribute){
if(attribute instanceof UniqueAttribute)
((UniqueAttribute)attribute).setAsset(this);
attributeList.add(attribute);
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,由于它们位于不同的包中,因此UniqueAttribute.setAsset()必须是公共的.这使得该方法对引擎的外部用户开放,并且虽然我可以通过直接使用这种方法来解决它是一个错误 - 它似乎相当草率.
第二个选项是在构造时为UniqueAttribute提供Asset,这意味着创建时的代码看起来像这样:
asset.addAttribute(new UniqueAttribute(asset));
Run Code Online (Sandbox Code Playgroud)
虽然我可以添加check-and-throwable或assert来确认传入了正确的资产,但我基本上依赖于用户连接这两者,我也不愿意这样做.
第三种选择是咬住子弹并将50个java文件全部放入同一个包中,这样我就可以使用标准的可见性.
是否有某种图案或某种东西可以帮助将这两者联系在一起而不会暴露电线,或者迫使我将所有东西都放入一个大包装中?
不相关的咆哮:我一直不喜欢java中的子包的概念并没有真正以任何有意义的方式扩展.就java而言,一个子包只是一个不同的包,并且在很多情况下我可以使用与此直接相关的更多可见性修饰符.
我有一个独立的应用程序,其职责之一是获取*.jrxml文件的路径并进行编译.
我可以毫无问题地执行此操作,直到带有子报表的报表出现,其中master的编译不会编译其子任务,从而导致稍后在轨道下找不到子报表*.jasper文件.
有什么办法吗?
1)设置JasperCompileManager以自动获取子报告?
2)获取JasperDesign或JasperReport对象中包含的子报表的路径列表?
我无法直接访问jrxml文件,因此修改报告以适应编译方法不是一种选择,也不应用任何标准命名方案来推断哪些子报告属于哪些报告.
这里有一个类似的问题:
http://jasperforge.org/plugins/espforum/view.php?group_id=102&forumid=103&topicid=40683
其中JRVisitor用于生成JRSubreport对象的列表,但是没有解释如何使用它来获取子报表的路径以便编译它并递归地查找子报表的子报表,我无法弄清楚它.
(我正在使用Eclipse Luna 4.4.0,JDK 1.8.0_05)
我正在制作游戏,游戏世界的拓扑结构可以粗略地分解World -> Level -> Tile,其中Tile是一个小的地形单位.我设置了三个项目,一个包含这些结构的一些基类,另外两个是服务器和客户端,它们扩展了基础项目中的结构,以满足每个项目所需的其他内容.像这样:
基地项目:
public class BaseWorld{/* ...code... */}
public class BaseLevel{/* ...code... */}
public class BaseTile{/* ...code... */}
Run Code Online (Sandbox Code Playgroud)
在服务器和客户端项目中:
public class World extends BaseWorld{/* ...extended code... */}
public class Level extends BaseLevel{/* ...extended code... */}
public class Tile extends BaseTile{/* ...extended code... */}
Run Code Online (Sandbox Code Playgroud)
现在在基础项目的许多部分中,有一些返回基类的方法,但在服务器和客户端项目中,这通常意味着我必须重写方法并转换为子类型,因为子项目专门使用子项类型.像这样:
public class BaseLevel{
BaseLevel getNextLevel(){/* ...code... */}
}
public class Level extends BaseLevel{
Level getNextLevel(){
return (Level)super.getNextLevel();
}
}
Run Code Online (Sandbox Code Playgroud)
这是一种难以维持的痛苦.我发现我可以使用泛型来解决其中的一些问题,具有以下模式:
public class BaseLevel<Level extends BaseLevel<Level>>{
Level getNextLevel(){/* …Run Code Online (Sandbox Code Playgroud) 我正在使用反射创建一个对象.根据构造的实际对象,构造函数可能具有特定自定义异常的throws声明,重要的是我可以捕获它.
不幸的是,当我尝试将异常添加到包含反射结构的try块的catch时,代码将无法编译,因为:
"无法访问的catch块.此异常永远不会从try语句主体中抛出"
我意识到捕获基类Exception会起作用,事实上我的代码也可以.然而,情况可能并非总是如此,因为未来其他对象可能适用于其他对象,并且在catch中使用instanceof并重新抛出其他所有内容似乎不够优雅.
有没有办法表明可能会抛出此异常,以便我可以专门捕获它?
编辑:根据要求编写一些代码.因为上面没有编译.
try{
Constructor<? extends Thing> constructor = getClassType().getDeclaredConstructor(SomeParameter.class);
Thing thing = constructor.newInstance(new SomeParameter());
}
catch(FoobarException e){
//new Thing(SomeParameter p) might throw this
}
catch(ReflectiveOperationException | IllegalArgumentException | SecurityException e){}
Run Code Online (Sandbox Code Playgroud) 我想更多地了解线程睡眠分辨率的工作原理,以及它与 sleep() 的分辨率无关的内容。
我知道它是由操作系统定义的,而在 Windows 上它通常是 15 毫秒。我最近无法通过环顾四周来确认这一点,但我依稀记得这 15 毫秒是由操作系统循环的,并且对所有线程都是“全局的”,这意味着 15 毫秒不是线程可以休眠的最短时间,而是sleep(1) 的最大值。那正确吗?所有操作系统都一样吗(超出持续时间)?
我想不出这可能很重要的情况,但是线程的虚假唤醒是否总是发生在此睡眠周期的动作点,还是可以随时发生?
在同步块上,等待线程是否有效地休眠(1)并在每个周期检查锁,还是退出块的线程立即唤醒等待线程?这对所有操作系统都一样吗?
当线程在wait()之后被notify()-ed时,它在等待锁定时会以与上面相同的方式处理,还是不同?
从性能的角度来看,还有其他时间 15ms 循环是相关的吗?
java ×9
generics ×3
types ×2
android ×1
eclipse ×1
exception ×1
hyperlink ×1
reference ×1
reflection ×1
report ×1
reporting ×1
return ×1
return-type ×1
return-value ×1
sleep ×1
thread-sleep ×1
unique ×1
volatile ×1
while-loop ×1