Given, for example, a class like this:
public abstract class AbstractSomething {
public static volatile SingularAttribute<Somefield, AnotherField> myAttribute;
}
how can I get an instance of myAttribute via reflection. There are no implementing classes for AbstractSomething.
EDIT
No, we need an instance of the SingularAttribute<T, S>. And the reason we need to use reflection is becuase these classes are generated and passed into our method as a Class object. We have no way no know which AbstractSomething we are receiving. There are quite a few of them.
EDIT 2
Found out what the issue was. When a Hibernate context is present in the application, the interfaces on the abstract class are replaced with their implementation counterparts when accessing them.
No big deal actually, you can do something like this:
Field field = AbstractSomething.class.getField("myAttribute")
And then you can access it by invoking field.get(null) and field.set(null, value)
The real question is WHY do you want to use reflection, but I guess you have your reasons.
EDIT:
If you have a Class instance in before hand (lets call it classInstance) then you can do
Field field = classInstance.getField("myAttribute")
to get the Field that reificates the field you are looking for... and if you want all fields just invoke the getFields method.
You don't really need a concrete implementation nor an instance of the reificated class in question in order to access the static fields.
No need for reflection. The field belongs to the class, and no matter how many subclasses there are, there is only one instance of the AbstractSomething class, so just:
SingularAttribute<Somefield, AnotherField> attr = AbstractSomething.myAttribute;
Related
Does anyone know if there's any way to intercept field accesses on the accessed class with Javassits?
public class Original{
public int field;
}
public class User {
Original o;
...
public int query(){
return o.field;
}
public void set(){
o.field=3;
}
}
What I want is that whenever another class accesses the field from any original instance, it runs some extra code (e.g. System.out.println("Reading field");)
I know that extending the class javassist.expr.ExprEditor and implementing the method void edit(FieldAccess fa), I can replace the field access for any other code that I want, but on the accessing class.
This requires to modify any class accessing that field. In our example the User class a replace all the read accesses by System.out.println(...);XXX=o.field, and all the write accesses by System.out.println(...);o.field=XXX
What I want to do is to convert a regular class instance into a proxy so any field access triggers a method execution. Is it feasible? Does it have any impact on possible subclasses?
Thanks in advance!
One way to do it is making all your proxy's fields private, and of course provide corresponding setters/getters, after that, you would implement a MethodHandler which will contain the method that you want to execute (ie. invoke) and you need to imeplement a MethodFilter in which you will designate which methods you want to intercept (in your case the getters/setters)
I think you're already familiar with javassist, so no code samples are needed i think, otherwise, i can edit this post to provide examples
I hope you get the idea ;)
So if I have a method where a variable can be an instance of a bunch of different classes where only some of them have a specific instance variable, how do I use this instance variable in the method without getting the cannot be resolved or is not a field error?
consider this code:
void method1(){
SuperType randomInstance = getRandomInstance();
if(randomInstance.stop == true) //do something
}
where SuperType is a super class to all possible instances that randomInstance can hold.
However, an instance doesn't necessarily have the variable stop so I get an error saying stop cannot be resolved or is not a field
So my question is, is there a way to get around this or would I have to create different methods for different instances depending on if they have the variable stop or not?
If having a stop property can be viewed as a behavior shared by some of the sub-classes of SuperType, you can consider defining an interface - let's call it Stoppable - having methods getStop (or perhaps isStopped if it's a boolean) and setStop.
Then your code can look like :
void method1(){
SuperType randomInstance = getRandomInstance();
if (randomInstance instanceof Stoppable) {
Stoppable sInstance = (Stoppable) randomInstance;
if(sInstance.getStop() == ...) //do something
}
}
Give the classes in question a common supertype or interface (they seem, from your code, to have one — SuperType), and define the instance field (it's not a "variable") on the supertype or define a getter function on the interface. (Actually, even if the supertype is a class, it's commonly best practice to define the field using a getter anyway, even if you could make it a public or protected instance field.)
If you cannot change your class hiearchy with the introdution of an Interface (Stoppable for example) can resort to reflection to detect if the class has a provate field named stop.
You can find an example of field "listing" from a class here and Field is documented here
I have a question about Java.
I have a class Say.java that has some methods, like sayHello(), saySomething(), sayBye(), ...
I have other classes too. I have a class Person, and two subclasses of Person: Senior and Junior.
My job to do is the following:
I have to set the Say.java class to be private, and create a public class SayFactory.java, with a method called getInstance. Then, to create a new instance of the Say.java class, I have to call my getInstance method with one argument: an instance of either Senior.java or Junior.java. If I create an instance of Say.java using a Senior.java object, I must be able to access all of the methods of Say.java. But if I do the same thing with Junior.java, I should be able to access all of Say.java's methods EXCEPT saySomething().
Can someone please explain how to do this and how it works?
Apologies by the way - I'm from Spain so my English isn't that great. If you don't understand the question, let me know and I'll try to write it out more clearly.
First refer to this as answer to making a class private: Java: Why can we define a top level class as private?
For the objects that you want "private" you will have to make all the fields and possibly methods of it private (depending on what you need). Then as #user1071777 mentioned set up public getters and setters.
Some basic information on calling methods of an object:
http://docs.oracle.com/javase/tutorial/java/javaOO/usingobject.html
To create the connection between classes you can have a class have another class as part of its definition and set it up through constructor or public setter.
I know that I can't write Private Class but I can do a inner class.
I have a class SayFactory and within this I got another called Say
The SayFactory have a method called getInstance(), and in this method I create an object of Say class and return this object. The problem is, how to deny access to method saySomething() if the parameter of getInstance() is a object of Junior.
I was wondering if it's possible to use a variable of a java class in another java class.Suppose variable Time is defined and calculated in Class A, how can I use it in Class B?
Other answers have suggested increasing a variable's visibility. Don't do this. It breaks encapsulation: the fact that your class uses a field to store a particular piece of information is an implementation detail; you should expose relevant information via the class's API (its methods) instead. You should make fields private in almost all cases.
Likewise, some other answers have suggested possibly making the variable static. Don't do this arbitrarily. You need to understand what static really means: it's saying that this piece of information is related to the type rather than to any one particular instance of the type. Occasionally that's appropriate, but it's generally a road towards less testable code - and in many cases it's clearly wrong. For example, a Person class may well have a name variable, but that certainly shouldn't be static - it's clearly a piece of information about a single person.
You should think carefully before exposing information anyway - consider whether there's a wider operation which the class in question could expose, instead of just giving away its data piecemeal - but when you do want to expose a field's value, use a property. For example:
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
By exposing it via a method, you can later change the implementation details without breaking existing clients.
Then from another class, you'd just call the getName() method:
// However you end up getting a reference to an instance of Person
Person person = ...;
String name = person.getName();
If you do have a static field, you can expose the value in the same way, but with a static method, which you'd call using the class name.
Be careful about returning values which are mutable, e.g. java.util.Date. This is another reason for using a getter method instead of allowing direct access to the field - you can make the method return a defensive copy where you need to.
If it is declared as public, you may use ClassA.yourVariable. On the other hand, for private access modifier, include the getter to your ClassA. On the ClassB, call ClassA.getYourVariable().
Also read about access specifiers in Java it might help.
If the variable is static, you can refer to it as A.Time from any code that has access to the variable. There's only one Time value for all of class A. If it is an instance variable, and you have an instance a of class A, you can refer to the variable as a.Time. There's a separate value for each instance of class A.
This is subject to Java's access rules:
if the field is public, any code can access it (this makes public variables kind of dangerous unless they are also declared final)
if the field is protected, only code in the same package or in a subclass of A can access it
if the field has default access, only code in the same package as class A can access it
if the field is private, only code in class A (including inner classes of A) can access it.
Alternatively, you can provide an accessor method in class A:
public class A {
. . .
public class getTime() {
return this.Time; // the "this." is optional
}
}
If you declare your Variable as public or static you will be able to access it from another class.
WHICH IS A VERY VERY BAD IDEA :)
In my current project I have a class which stores its Instance in a variable. This Instance should be accesible by all other classes in the project, but it may only be altered by its own class.
How can I achieve this?
Write a public getter but no public setter. And the field itself private
In short that is called immutable object, state of Object cannot change after it is constructed.
String is a common example of immutable Class.
Make a class immutable by following-
ensure the class cannot be overridden - make the class final, or use
static factories and keep constructors private.
make fields private and final
force callers to construct an object completely in a single step,
instead of using a no-argument constructor combined with subsequent
calls to setXXX methods.
do not provide any methods which can change the state of the object
in any way - not just setXXX methods, but any method which can change
state
if the class has any mutable object fields, then they must be
defensively copied when passed between the class and its caller.
Someone suggests "public getter but no public setter for the private field."
Caution: This would only work if the field is primitive type.
If it is an object with setters, the content can still be modified; thus not read-only.
It will be interesting to see Java language provide some constructs to make a return type read-only without having to do a deep-copy / clone.
i'm imaging like
ReadOnly getEmployee() {
...}
The boilerplate code for instantiating a singleton can be found in many places, see for example http://www.javacoffeebreak.com/articles/designpatterns/index.html
Be aware that many consider the singleton to be an antipattern because it's pretty hard to get rid of once your application is littered with references to the singleton.