小编Joh*_*ers的帖子

如何从泛型类型参数中获取`.class`属性?

此问题的已接受答案描述了如何TGeneric<T>类中创建实例.这涉及将Class<T>参数传递给Generic构造函数并newInstance从中调用方法.

Generic<Bar>然后创建一个新实例,并Bar.class传入参数.

如果新Generic类的泛型类型参数不是某个已知的类,Bar但它本身是泛型类型参数,您会怎么做?假设我有一些其他类Skeet<J>,我想Generic<J>从该类内部创建一个新实例.然后,如果我尝试传入,J.class我得到以下编译器错误:

cannot select from a type variable.
Run Code Online (Sandbox Code Playgroud)

有没有办法解决?

触发错误的代码的具体位是:

public class InputField<W extends Component & WidgetInterface>
                                                 extends InputFieldArray<W>
{
  public InputField(String labelText)
  {
    super(new String[] {labelText}, W.class);
  }
  /* ... */
}

public class InputFieldArray<W extends Component & WidgetInterface>
                                                                 extends JPanel
{
   /* ... */
  public InputFieldArray(String[] labelText, Class<W> clazz)
                          throws InstantiationException, IllegalAccessException
  { …
Run Code Online (Sandbox Code Playgroud)

java generics

64
推荐指数
3
解决办法
2万
查看次数

如何在Java中实现抽象静态方法?

关于包含静态抽象Java方法的不可能性存在许多问题.关于此的解决方法(设计缺陷/设计强度)也有很多.但我找不到任何关于我即将陈述的具体问题.

在我看来,制作Java的人和很多使用Java的人并没有像我和其他许多人那样思考静态方法 - 作为类函数或属于类的方法而不是任何对象.那么还有其他一些实现类函数的方法吗?

这是我的例子:在数学中,一个是一组对象,可以使用某些操作*以某种合理的方式相互组合 - 例如,正实数在正常乘法下形成一组(x*y = x × y),并且整数组形成一组,其中"乘法"运算是加法(m*n = m + n).

在Java中对此进行建模的一种自然方法是为组定义接口(或抽象类):

public interface GroupElement
{
  /**
  /* Composes with a new group element.
  /* @param elementToComposeWith - the new group element to compose with.
  /* @return The composition of the two elements.
   */
  public GroupElement compose(GroupElement elementToComposeWith)
}
Run Code Online (Sandbox Code Playgroud)

我们可以为上面给出的两个例子实现这个接口:

public class PosReal implements GroupElement
{
  private double value;

  // getter and setter for this field …
Run Code Online (Sandbox Code Playgroud)

java oop static interface abstract

13
推荐指数
1
解决办法
2万
查看次数

使用XML在此Java程序中传输数据的优缺点是什么?

我被要求为用Java编写的现有shell/cmdline程序编写GUI,我想在GUI和原始程序之间创建一个抽象层,以便于添加不同的GUI(Web界面,例如,而不是桌面应用程序).目前,该计划的结构如下:

命令行选项被立即转换为一个Java散列表(以一个选项如-f opt到散列"-f=>opt".这些选项,然后用于建立environment对象,该对象的程序使用.

我想到的结构是:

在实线之后,这意味着GUI生成一个XML文件,其中包含与shell/cmdline选项相同的信息,然后用于设置environment选项.

问题是,我不太确定这是否是最好的工作方式(虚线,表示替代结构),我也不知道XML是否是正确的选择.

就目前而言,environment从中设置对象的程序options部分与使用它environment获取结果的部分位于相同的方法中.因此,实现将shell/cmdline参数直接送入程序的内容比实现将信息作为XML文件传递的结构更容易.我当然不想创建XML文件,然后将其转换为shell选项并将其转移到程序中,但是GUI可能更有意义生成shell选项而不是创建XML.

据我所知,使用XML文件的主要优点是它使未来开发人员的工作更容易,因为他们可以使用现有的库来创建XML文件,而不必担心-a opt1 -b opt2 -c opt3 [...]正确的语法.

另一方面,我听说尝试创建自己的XML语言是不容忽视的(尽管程序可以将数据存储在没有DTD的XML文件中,甚至可以告诉我的架构).

我的方法或多或少是正确的吗?或者我使用完全不合适的工具来完成我正在尝试的工作?

java xml user-interface

10
推荐指数
1
解决办法
1199
查看次数

java - 有多少个类太多了?什么时候添加新类?

这是一个一般性的问题,但我会首先给你我的具体问题:

我正在为我的程序编写一个GUI,用于一个程序,该程序将采用框架的形式,其中放置了各种小部件(标签,文本字段等).它最初将使用该javax.swing库,但我在库和GUI本身之间设置了一层抽象,以便更容易创建执行相同操作的Web应用程序.

我希望有一个代表GUI布局的类:也就是说,它应该包含有关各种标签,按钮等放置在内容窗格中的位置的所有信息.目前,我正在考虑的实施如下:

class Layout
{
  public MyLabel titleLabel;
  public myTextField sequenceTextField;
  [...]

  public void drawTitleLabel()
  {
    titleLabel = new MyLabel("This is the title.");
    titleLabel.setLocation(wherever);
    titleLabel.draw();
  }

  public void drawSequenceTextField()
  {
    sequenceTextField = new MyTextField();
    [...]
    sequenceTextField.draw();
  }

  [...]

  public void drawGuiFrame()
  {
    drawTitleLabel();
    drawSequenceTextField();
    [...]
  }
}
Run Code Online (Sandbox Code Playgroud)

因此,我将内容窗格上的每个窗口小部件声明为该类的字段Layout,然后创建drawWidgetName绘制每个窗口小部件的方法.最后,我创建了一个方法来调用每个draw...方法以绘制整个GUI.

但这似乎是错误的.这些draw...方法感觉好像它们应该是各个小部件本身的方法,而不是整个GUI的大规模布局.这表明,我应该创建单独的类TitleLabel,SequenceTextField等等,每一个draw方法,然后只是有一个drawGuiFrame在方法Layout调用所有这些类的draw方法(我甚至可以创建一个抽象类,这些新类可以扩展).

这会有一些其他直接的好处.假设我想要合并一个复选框系统以及我的标签和文本区域.然后,我可以宣布,作为其自己的类,并给它的属性isOptionA,isOptionB等等,以记录其复选框选中了.

但是我有点不愿意以这种方式实现GUI,原因有两个.首先,创建这么多新类会使代码库与大量小.java文件混乱.其次,这些将是非常"单一使用"类:我永远不会再使用代码,因为类将纯粹为这个特定的GUI设计. …

java oop user-interface

7
推荐指数
1
解决办法
3419
查看次数

在插入模式下是否有键盘快捷键告诉vim我不想再在评论中?

当我用//Java 编写注释时,按Enter键,vim有助于//在下一行的开头添加一个.

// This is the first line of my comment <CR>
// <-- these were added automatically by auto-comment.
Run Code Online (Sandbox Code Playgroud)

正如我所说,这是有用的行为(我//用于多行注释,以便很容易注释掉大块代码/*...*/,并/**...*/仅用于Javadoc注释).但是当我到达评论结束时,我必须按三次退格键才能摆脱//我现在不再需要的行的开头.

是否有插入模式的键盘快捷键可以告诉Vim我不再写评论?或者我必须自己写?

vim autocommenting

5
推荐指数
1
解决办法
122
查看次数

Class <V>可以在泛型类型上采用多个边界吗?

以下代码编译:

import java.util.ArrayList;

public class ClassTest
{
  private ArrayList<Class<? extends Interface1>> testClass = 
    new ArrayList<Class<? extends Interface1>>();

  private interface Interface1 {}
}
Run Code Online (Sandbox Code Playgroud)

但是以下代码会产生六个错误:

import java.util.ArrayList;

public class ClassTest
{
  private ArrayList<Class<? extends Interface1 & Interface2>> testClass = 
    new ArrayList<Class<? extends Interface1 & Interface2>>();

  private interface Interface1 {}
  private interface Interface2 {}
}
Run Code Online (Sandbox Code Playgroud)

错误:

ClassTest.java:5: > expected
  private ArrayList<Class<? extends Interface1 & Interface2>> testClass = 
                                              ^
ClassTest.java:5: ';' expected
  private ArrayList<Class<? extends Interface1 & Interface2>> testClass = 
                                                           ^
ClassTest.java:5: <identifier> expected …
Run Code Online (Sandbox Code Playgroud)

java generics

5
推荐指数
1
解决办法
517
查看次数

私有方法和公共领域一样糟糕吗?

请原谅挑衅性问题标题.众所周知,你永远不应该在Java程序中使用公共字段(除了类似结构的类,你应该避免使用它).但人们谈论硬币的另一面 - 私人方法.

我看到它的方式是:如果你有私有方法,那么你正在编写本地程序代码.具有私有字段的Java类和调用许多私有方法的一些公共方法,以及具有全局变量和一些函数的C模块之间基本上没有区别,其中一些是在extern其他地方编写的(除了相当大的区别之外)你不能实例化一个C模块).鉴于很多关心良好Java实践的人都认为你应该尽可能远离程序性的工作,我很惊讶没有更多的指导方针限制私有方法的使用.

请注意,我不想暗示任何人都认为永远不应该使用私有方法(或者它们实际上和公共字段一样糟糕).但这是我的问题,我尽量做到尽可能客观:

  • 是否有任何标准Java指南限制私有方法的使用? (标准指南的一个例子是"没有公共领域" - 尽管你可能认为这是一个意见问题,但是很多人普遍认为不使用公共领域是好的做法).
  • 如何使用私有方法绕过?(例如,通过声明私有和使用公共get/set方法,可以使用公共字段进行循环.如果我有一个包含大量私有方法的类,我想我应该创建一个新类来保存它们但是,如果我这样做,那么我冒着编写一个从未实例化过的Java类的风险,并且行为与C模块完全相同. 是否有任何广泛使用的设计模式可以帮助我减少类中私有方法的数量?)

java oop

4
推荐指数
1
解决办法
1262
查看次数

为什么我的按位操作不适用于Java中的`int`s?

我刚刚得到以下编译器错误:

./package/path/FrameScreenPosition.java:80: incompatible types
found   : int
required: boolean
    if (frame.getExtendedState() & Frame.MAXIMIZED_BOTH) {
                                 ^
Run Code Online (Sandbox Code Playgroud)

"扩展状态"是各种不同状态的按位掩码,例如最大化或图标化,我试图测试帧是否最大化.以下简短示例产生类似的错误:

public class BitTest
{
  public static void main(String[] args)
  {
    int a = 1;
    int c = 3;

    if (a & c) {
      System.out.println("This is right.");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我所看到的一切都表明,按位运算符&不限于Java中的布尔变量,为什么我会收到错误消息?

java

2
推荐指数
1
解决办法
495
查看次数

fgets在gdb下遇到分段错误,但在正常运行时却没有

以下程序(什么都不做)运行正常.

#include <stdio.h>

int main(int argc, char *argv[])
{
  char *current_string = NULL;
  fgets(current_string, 16, stdin);

  return(0);
}
Run Code Online (Sandbox Code Playgroud)

但是,当我在GDB下运行它时,该fgets调用会触发分段错误.

Program received signal SIGSEGV, Segmentation fault.
0x000000332ec67ee0 in _IO_getline_info_internal () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6_6.9.x86_64
(gdb) backtrace
#0  0x000000332ec67ee0 in _IO_getline_info_internal () from /lib64/libc.so.6
#1  0x000000332ec66d29 in fgets () from /lib64/libc.so.6
#2  0x0000000000400536 in main (argc=1, argv=0x7fffffffd4e8) at test.c:7
Run Code Online (Sandbox Code Playgroud)

据我所知,我一直在关注该fgets函数的正确用法,我不明白发生了什么.我做错了什么?

我正在用gcc编译-gRHEL上的选项(用于调试信息).

c pointers segmentation-fault

2
推荐指数
1
解决办法
517
查看次数

gcc 是否将长字符串初始化为 `""` 而不是短字符串?

注意: 我知道读取未初始化的字符串是未定义的行为。这个问题具体是关于 GCC 的实施。

\n

我使用的是 GCC 版本 6.2.1,并且我观察到长度大于 100 左右的未初始化字符串被初始化为"". 读取未初始化的字符串是未定义的行为,因此编译器可以""根据需要随意将其设置为,并且当字符串足够长时,GCC 似乎会这样做。当然,我永远不会在生产代码中依赖这种行为 - 我只是好奇这种行为在 GCC 中来自哪里。如果它不在 GCC 代码中的某个地方,那么它不断发生就是一个非常奇怪的巧合。

\n

如果我写下面的程序

\n
/* string_initialization.c */\n#include <stdio.h>\n\nint main()\n{\n  char short_string[10];\n  char long_string[100];\n  char long_long_string[1000];\n\n  printf("%s\\n", short_string);\n  printf("%s\\n", long_string);\n  printf("%s\\n", long_long_string);\n\n  return(0);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

并用 GCC 编译并运行它,我得到:

\n
$ ./string_initialization\n\xef\xbf\xbdQE\xef\xbf\xbd\n\n\n$\n
Run Code Online (Sandbox Code Playgroud)\n

(有时第一个字符串也是空的)。这表明如果字符串足够长,GCC 会将其初始化为"",但否则并不总是这样做。

\n

如果我用 GCC 编译以下程序并运行它:

\n
#include <stdio.h>\n\nint main()\n{\n  char long_string[100];\n  int i;\n\n  for (i = 0 ; i < 100 ; ++i)\n  {\n    printf("%d …
Run Code Online (Sandbox Code Playgroud)

c gcc undefined-behavior

2
推荐指数
1
解决办法
188
查看次数

有没有办法转换这些不可转换的类型?

乍一看,我本来希望能够演员

ArrayList<Class<? extends Interface1>> 
Run Code Online (Sandbox Code Playgroud)

ArrayList<Class<?>>
Run Code Online (Sandbox Code Playgroud)

因为第二个显然是第一个限制较少的版本.但是,以下代码无法编译:

import java.util.ArrayList;

public class TypeInvocationConversionTest
{
  private static ArrayList<Class<? extends Interface1>> classList;

  private static ArrayList<Class<?>> lessRestrictiveClassList;

  public static void main(String[] args)
  {
    classList = new ArrayList<Class<? extends Interface1>>();
    lessRestrictiveClassList = (ArrayList<Class<?>>) classList;
  }

  private interface Interface1 {}
}
Run Code Online (Sandbox Code Playgroud)

但会产生错误

TypeInvocationConversionTest.java:12: inconvertible types
found   : java.util.ArrayList<java.lang.Class<? extends TypeInvocationConversionTest.Interface1>>
required: java.util.ArrayList<java.lang.Class<?>>
    lessRestrictiveClassList = (ArrayList<Class<?>>) classList;
                                                     ^
Run Code Online (Sandbox Code Playgroud)

我不认为想要转换这两种类型是不合理的:为了激励,这里是一个更接近我实际处理的短程序(这段代码不能编译):

import java.util.ArrayList;

public class Mammal
{
  public void produceMilk() {}
}

public class Reptile
{
  public …
Run Code Online (Sandbox Code Playgroud)

java generics

1
推荐指数
1
解决办法
3550
查看次数