首页 \ 问答 \ 为什么Java方法参数可以显式协变?(Why can Java method parameters be explicitly covariant?)

为什么Java方法参数可以显式协变?(Why can Java method parameters be explicitly covariant?)

在Java中,您可以使用extends关键字声明给定的类型参数是协变的。 协方差和逆变确实让我感到困惑,但我想我已经对它们有了一般的认识。 但是,在我的测试中,似乎Java类型参数本质上是协变的。 那么我们为什么要明确说明呢?

例如,我构建了一个如下所示的快速示例:

public class Main<E> {

    protected E value;

    public Main(E value) {
        this.value = value;
    }

    public <T extends E> void setValue(T value) {
        this.value = value;
    }

    public E getValue() {
        return value;
    }

    public static void main(String[] args) {
        Main<Number> example = new Main<Number>(0L);
        System.out.println(example.getValue().getClass().getCanonicalName());
        example.setValue(32.0);
        System.out.println(example.getValue().getClass().getCanonicalName());
    }
}

使用的类型是Number,所有盒装类型的超类。 在构造函数中,它接受一个声明为E类型的参数(在本例中为Number)。 另一方面,在setValue方法中,它接受一个声明为扩展类型E的参数。两个println调用都返回正确的值(首先是java.lang.Long ,然后是java.lang.Double )。

我看到它的方式,删除泛型,你仍然可以传递子类。 如果声明的类没有类型参数,并且方法/构造函数接受/返回Numbers,它仍然可以正常工作。

那么在这种情况下extends关键字的目的是什么?


In Java, you can use the extends keyword to declare that a given type parameter is covariant. Covariance and contravariance do confuse me a bit, but I think I've gotten a general sense of them. However, in my tests, it seems that Java type parameters are inherently covariant. So why can we explicitly state it?

For example, I built a quick sample that looks like this:

public class Main<E> {

    protected E value;

    public Main(E value) {
        this.value = value;
    }

    public <T extends E> void setValue(T value) {
        this.value = value;
    }

    public E getValue() {
        return value;
    }

    public static void main(String[] args) {
        Main<Number> example = new Main<Number>(0L);
        System.out.println(example.getValue().getClass().getCanonicalName());
        example.setValue(32.0);
        System.out.println(example.getValue().getClass().getCanonicalName());
    }
}

The type used is Number, the superclass of all the boxed types. In the constructor, it takes a parameter which is declared of type E (in this case Number). In the setValue method, on the other hand, it takes a parameter which is declared to be anything extending type E. Both println calls return the proper value (first java.lang.Long, then java.lang.Double).

The way I see it, removing generics, you can still pass subclasses. If the class was declared with no type parameters and the methods/constructor took/returned Numbers, it'd still work properly.

So what is the purpose of the extends keyword in this case?


原文:https://stackoverflow.com/questions/25717291
更新时间:2022-05-22 16:05

最满意答案

回答这个问题:

我们进行了一些测试,我们发现当我们在IIS中添加绑定时,它不会更新我们服务的配置文件。 这意味着我们需要在两个不同的地方保持配置。 这不是逻辑的吧?

当您使用IIS托管您的服务时,您必须配置您的App.config文件或web.config文件以允许IIS公开一些绑定,因此在您的配置文件中,您将所有绑定到您的wcf服务。 Http,net.tcp等...

在你的绑定中你不会指定地址,因为你将直接在IIS中指定这些地址。

在IIS中,您必须允许在您的网站的高级设置中可用的绑定。 之后,您将为您的网站“Web服务”设置新的绑定,并添加您要收听的每个绑定,并指定该地址。

您将直接在IIS中指定地址。

有一个例子

您的配置文件:

<services>
    <service name="ServiceName">                    
        <endpoint address=""
            binding="basicHttpBinding"
            bindingConfiguration="httpMode"
            contract="IContract" />                 
        <endpoint address=""
            binding="netTcpBinding"
            contract="IContract" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    </service>
</services>

在你的IIS中,你会放弃你的设置

http,net.tcp在启用协议

之后,您将绑定到IIS中。 把你的绑定为http normaly并添加一个新绑定的net.tcp,在绑定配置中放入端口和虚拟目录

8001:*

此设置允许所有连接到任何虚拟目录的8001端口。

您还必须在服务器上安装“WCF激活(Http激活和非Http激活)”功能。


To answer at those question :

We ran some tests and we found out that when we're adding bindings in IIS, it doesn't update config file of our service. That means that we would need to maintain the configuration in two different places. It's not logic, right ?

When you use IIS to host your service, you must configure your App.config file or web.config file to allow IIS to expose some binding, so in your configuration file, you will put all your binding you allow to your wcf service. Http, net.tcp etc...

In your binding you will not specified address, because you will specified those address in IIS directly.

In IIS you must allow the binding available in the advanced settings of your web site. After that you will set new binding for your web site "web service" and add every bindings you want listen, and specify the address.

You will specify the address directly in IIS.

There's an example.

Your configuration file:

<services>
    <service name="ServiceName">                    
        <endpoint address=""
            binding="basicHttpBinding"
            bindingConfiguration="httpMode"
            contract="IContract" />                 
        <endpoint address=""
            binding="netTcpBinding"
            contract="IContract" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    </service>
</services>

In your IIS advenced setting your will put

http,net.tcp in Enabled Protocols

After that you will go in your binding into IIS. Put your binding for http normaly and add a new binding net.tcp, in the binding configuration put the port and virtual directory like

8001:*

This setting allow all connection into the 8001 port for any virtual directory.

You also must to have the feature "WCF Activation, (Http activation and Non-Http Activation)" installed on your server.

相关问答

更多
  • 比较IIS Express的工作安装和失败的安装后,我们发现问题在于用户的主目录中没有带有一些配置文件的“IISExpress \ config”文件夹。 此文件夹仅在安装了IIS Express的用户的主目录中创建。 只需将“config”文件夹复制到“My Documents \ IISExpress”中其他用户的主目录中,我们就可以运行Web服务而不会出现其他问题。 希望这有助于其他可能会遇到同样问题的人。 After comparing a working installation of IIS E ...
  • 回答这个问题: 我们进行了一些测试,我们发现当我们在IIS中添加绑定时,它不会更新我们服务的配置文件。 这意味着我们需要在两个不同的地方保持配置。 这不是逻辑的吧? 当您使用IIS托管您的服务时,您必须配置您的App.config文件或web.config文件以允许IIS公开一些绑定,因此在您的配置文件中,您将所有绑定到您的wcf服务。 Http,net.tcp等... 在你的绑定中你不会指定地址,因为你将直接在IIS中指定这些地址。 在IIS中,您必须允许在您的网站的高级设置中可用的绑定。 之后,您将为您 ...
  • 我相信问题是我没有在Windows的SysWOW64目录中使用特殊的64位程序(仍称为regsvr32)注册.dll。 请参阅:将32位COM DLL注册到64位Windows 7 实际上我在发布之前就找到了这个解决方案,并且认为我已经尝试了它并且仍然得到例外,但也许我错了。 这个解决方案似乎有效。 它甚至可能需要重启服务器或至少重启IIS。 I believe the problem was that I wasn't registering the .dll with the special 64-bi ...
  • 有两种可能性: 它可能是版本差异。 您发送给服务的xml是相同的。 但是IIS 6上的C#dto类是不同的,因此反序列化错误。 您已经使用了一些仅使用.net框架4在WCF中支持的数据类型(例如枚举)。 尝试这个: 向接受字符串并返回字符串的联系人添加新方法。 检查它是否适用于两个macines 然后逐渐增加方法的复杂性,直到它与您的实际方法相匹配,在每次更改后进行测试。 The issue I was struggling with was not set max length of message's ...
  • 您必须编写多个自定义类以支持使用参数创建服务: 实现IInstanceProvider自定义类。 该类将负责使用非默认构造函数创建服务实例。 实现IServiceBehavior自定义类。 该类将负责将自定义实例提供程序添加到端点调度程序中。 自定义ServiceHost将应用您的行为。 自定义ServiceHostFactory将实例化您的自定义服务主机。 您将从.svc文件引用此工厂。 这通常与构建依赖注入支持相同。 您可以查看本文的示例。 You must write several custom c ...
  • 听起来像.NET 3.0 ISAPI映射消失了。 在.NET 3.0 WCF目录(C:\ Windows \ Microsoft.NET \ Framework \ v3.0 \ Windows Communication Foundation)中运行ServiceModelReg -r Sounds like the .NET 3.0 ISAPI mappings have vanished. In the .NET 3.0 WCF directory (C:\Windows\Microsoft.NET\ ...
  • 检查以确保你已经安装了框架3.5 sp1,之后进入程序,添加删除窗口功能,然后确保你有: 微软.net框架3.5.1下,确保两个选项都被选中:WCF HTTP激活和WCF非HTTP激活.... 如果这仍然不起作用更新发表评论在这里.... Check to make sure you have framework 3.5 sp1 installed, after this go to Programs, add remove windows features, then make sure you have ...
  • 1.我能否在不构建多个安装包的情况下安装同一服务的多个实例? 是的,在安装程序中配置您的服务名称。 端口也应该是可配置的,因此它不会与其他实例冲突。 2.WindowsLogin和CustomLogin会像以前一样工作吗? 是 3.在IIS中托管的启动时间有时可能长达1分钟,我在Windows服务中托管时看到了大约30个sek限制的内容? 我该如何处理? 要么启动异步,要么在OnStart()方法中调用this.RequestAdditionalTime 4.在开始这个项目之前,还有其他一些我应该考虑的事项 ...
  • 一个原因是IIS6仅支持基于HTTP的绑定。 如果要使用TCP,MSMQ等,则需要在单独的程序中进行托管。 One reason is that IIS6 only supports bindings based on HTTP. If you want to use TCP, MSMQ, etc., then you need to host in a separate program.
  • 尝试创建服务契约以处理使用basicHttpBinding公开的loadbalancer的请求 Try to create a service contract to handle the requests of the loadbalancer exposed using a basicHttpBinding

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)