1

At the moment, I am preparing for an exam which I will write in two days. At the example-questions I found the following question:

Will this compile?

FavoritesList<Person> l = new FavoritesList<Contact>();

(Contact extends Person)

I would have answered yes, because if I have the following:

FavoritesList<Person> l = new FavoritesList<Person>();
l.add(new Contact());

that's fine. Why isn't it fine in the first example?

keep in mind: Contact extends Person!

Thanks in advance Best regards


htaccess different behaviour with trailing slash on the URL

I have the following rules in .htaccess file placed at the root folder

RewriteEngine on

RewriteRule ^/?$ /testsite/index.php?rel=m
RewriteRule ^about/?$ /testsite/aboutus.php?rel=b
RewriteRule ^ict/?$ /testsite/ict.php?rel=b
RewriteRule ^eeap/?$ /testsite/eeap.php?rel=b

The rule for index works fine with or without a trailing slash. However when I hit http://mydomain.com/testsite/about/ the page is served without CSS and images and works fine if the last slash is removed. This happens with the rule for ict too.

For the next rule (eeap) things behave the other way. CSS and images go missing if I end the URL with a slash.

What am I doing wrong here?

4

7 回答 7

2

好吧,这是被禁止的,但让我指出原因

让我们考虑一下:

FavoritesList<Person> l = new FavoritesList<Contact>();

有些操作是允许FavoritesList<Person>但禁止的,FavoritesList<Contact>即添加任何Person违反合同的子类FavoritesList<Contact>

您可能正在寻找的是:

 FavoritesList<? extends Person> wildcardedList = new FavoritesList<Contact>();

这意味着:这是一个未指定类型的列表?,这个列表中的所有元素都是这个类型?,我们知道这个类型?是扩展人。请注意,这种类型的通配符起初可能不直观。基本上他们给你的是这个列表的只读视图。

让我们假设:

 class FavoritesList<T>{

    void add(T t){...}

 }

基本上你不能打电话:

 wildcardedList.add(new Contact()); 

也不:

 wildcardedList.add(new Contact()); 

因为我们不知道是否Person属于Contact未指定类型 T。

为此,您必须将通配符添加到add参数类型,然后它会变得混乱。

于 2013-06-30T19:04:01.117 回答
1

这不好,因为 Java 中的泛型不支持继承,这意味着FavoritesList<Contact>它不是FavoritesList<Person>
See this 的子类型:http: //docs.oracle.com/javase/tutorial/java/generics/inheritance.html

于 2013-06-30T19:00:51.713 回答
0

FavoritesList<Person> l = new FavoritesList<Contact>();你创建FavoritesListContacts。

但是通过引用FavoritesList<Person> l,您将能够添加任何类型的Person类或扩展 Person 的类的实例,例如让Employee该列表。

你认为它会安全吗?

于 2013-06-30T19:03:21.147 回答
0

这不能编译是有原因的,可以用数组观察到。

  Object[] objects = new String[10];
  objects[0] = new Object();

现在,这些行中的每一行都是有意义的。然而,我们最终将一个对象插入到一个字符串数组中,这当然是错误的并引发了异常。

后来添加了泛型,Java 开发人员决定修复此问题,aList<String>不兼容,List<Object>因为两者对其内容有不同的约束,但是他们添加了额外的语法,因此 aList<String>兼容List<? extends Object> (阅读:可以包含未知类型的列表目的)。

    List<String> stringList = ...
    List<Object> objectList = stringList; //error
    List<? extends Object> someList = stringList;//string is a subtype of object
    stringList.add("Hello");//add string to stringlist, works
    someList.add("Hello");// error exact type of list unknown
    String h1 = stringList.get(0);//get string from StringList 
    String h2 = someList.get(0);//error, can be any subtype of object
    Object h3 = someList.get(0);//get object from someList
    String h4 = (String)someList.get(0);//we know that somelist has a string
于 2013-06-30T19:11:10.537 回答
0

不,它不会起作用。Java 不提供泛型的协变属性,因此如果 Contact 扩展 Person 这并不意味着FavoritesList<Contact>扩展FavoritesList<Person>

于 2013-06-30T19:01:03.637 回答
0

想象一下,您有另一个 Person 子类(例如,Enemy,Enemy 扩展了 Person)。

然后,如果第一个被允许,你可以这样做:

FavoritesList<Contact> contacts = // a list of some Contacts
FavoritesList<Person> l = contacts;

// at this point, contacts and l both reference the same object!

l.add(new Enemy()); // allowed by the compiler since enemy is a person

// now contacts contains an enemy which is bad since Enemy is not a Contact!
Contact c = contacts.get(contacts.size() - 1); // would throw a class cast exception if the compiler allowed the above

请注意,Java 确实使用通配符为此提供了一种解决方法,因此您可以执行以下操作:

FavoritesList<Contact> contacts = // a list of some Contacts
FavoritesList<? extends Person> l = contacts;

Person person = l.get(0); // ok since we know everything in l is some class that extends Person
l.add(new Enemy()); // won't compile, since we can't verify that Enemy is the ?
于 2013-06-30T19:02:30.280 回答
0

这不好,因为允许它允许您将其他类型的Person插入到您的Contacts 列表中。虽然 s 的不可变列表确实Contact“是” s 的不可变列表Person,但 s 的可变列表不是Contacts 的可变列表Person- 您可以将非Contacts 插入到 s 的可变列表中Person,但不能插入s的可变列表Contact

因此,出于安全原因,Java 禁止您执行此类操作。你可以做的是这样的:

FavoritesList<? extends Person> l = new FavoritesList<Contact>();

这将是有效的,因为您不能插入非Contactvia aFavoritesList<? extends Person>并破坏您的列表。

其他语言(例如 C#、Scala)允许您为类型参数提供协变和逆变注释,以更好地控制在这种情况下允许的转换(例如,如果是这样,您可以将类型参数标记为协变,允许Thing<Derived>转换为Thing<Base>),但 Java 没有。这是一个关于该主题的 C# 参考,可能会使事情更清楚:

http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx

于 2013-06-30T19:02:53.413 回答